ReactJS - TypeError: невозможно прочитать свойство setState из undefined - LocalForage IndexedDB GraphQL

У меня проблемы с проектом React Example, который я пытаюсь обновить в учебных целях.

Исходный скрипт использует GraphQL для запроса данных из базы данных - я заменил его на LocalForage и стараюсь придерживаться исходного кода, однако он часто дает мне ошибки.

Все дело в строке 58:

    this.setState({items: value})

Исходную строку можно увидеть на 51:

//    .then(data => this.setState({items: data.data.listItems.items}))

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
//import { API, graphqlOperation }  from "aws-amplify";
//import * as queries from '../graphql/queries';
import localforage from 'localforage';


const styles = {
  card: {
    minWidth: 275,
  },
  bullet: {
    display: 'inline-block',
    margin: '0 2px',
    transform: 'scale(0.8)',
  },
  title: {
    fontSize: 14,
  },
  pos: {
    marginBottom: 12,
  },
  root: {
    display: 'flex',
    flexWrap: 'wrap',
    justifyContent: 'inherit',
    padding: '10px'
  },
};

class ListItems extends Component {

state = {
    items: []
  }

componentDidMount = () => {
    this.getItems()
  }

getItems = () => {
//    ORIGINAL GraphQL Query from project
//    API.graphql(graphqlOperation(queries.listItems))
//    .then(data => this.setState({items: data.data.listItems.items}))
// ------------------------------------------------------------

//    NEW LocalForage QUERY:
    localforage.getItem('MyDatabaseKey').then(function(value) {
    // This code runs once the value has been loaded
    // from the offline store.
    this.setState({items: value})
}).catch(function(err) {
    // This code runs if there were any errors
    console.info(err);
});



  };

render(){
    const { classes } = this.props;
    const { items } = this.state;
    const bull = <span className = {classes.bullet}>•</span>;
    return (
      <div className = {classes.root}>
      <Grid container className = {classes.root} spacing = {16}>
          {items.map(item => (
             <Grid key = {item.id} item>
                 <Card className = {classes.card}>
                   <CardContent>
                     <Typography className = {classes.title} color = "textSecondary" gutterBottom>
                       {item.name}
                     </Typography>
                      <Typography component = "p">
                      {item.price}
                      </Typography>
                      <br />
                      <Typography component = "p">
                      {item.description}
                      </Typography>
                  </CardContent>
                    <CardActions>
                     <Button size = "small">Edit Item</Button>
                   </CardActions>
                 </Card>
               </Grid>
             ))}
         </Grid>
      </div>
    );
  }
}

ListItems.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(ListItems);

Я получаю следующую ошибку:

TypeError: Cannot read property 'setState' of undefined
at listItems.js:58

Надеюсь, кто-нибудь из вас сможет мне помочь.

Большое спасибо за то, что нашли время!


Обновление 1:

По словам Джоша, я пробовал:

getItems = () => {
//    ORIGINAL GraphQL Query from project
//    API.graphql(graphqlOperation(queries.listItems))
//    .then(data => this.setState({items: data.data.listItems.items}))
// -----------------------------------------------------------------

//    NEW LocalForage QUERY:
localforage.getItem('MyDatabaseKey')
.then(value => this.setState({items: value}) )
.catch(function(err) {
    // This code runs if there were any errors
    console.info(err);
});

Однако это дает мне еще одну ошибку:

Снимок экрана

Можете ли вы попробовать инициализировать state в constructor?

Abrar 06.01.2019 08:35
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
272
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я считаю, что в обещании это неправильно. Вы пробовали заменить функцию (значение) {// код} на значение => // код?

Скорее всего, это связано с лексической областью видимости, которую предоставляют стрелочные функции.

Привет, Джош, спасибо за ваш вклад - только что попробовал, но получаю еще одну ошибку. См. Снимок экрана в обновлении Edit. - TypeError: невозможно прочитать свойство 'map', равное нулю.

Kap47 06.01.2019 02:19

Хорошо, вы можете распечатать состояние после вызова функции? Может случиться так, что value, для которого устанавливается state.item, тоже не является массивом

Josh 06.01.2019 02:23

Думаю, проблема в привязке "этого". в вашем обещании. тогда у вас нет «this», относящегося к компонентам вашего класса «this». вы можете определить функцию в своем классе, например updateState или что угодно, а затем передать ее «then».

пример:

class ListItems extends Component {
updateState = (value) => {
   this.setState({items: value})
}

getItems = () => {

 localforage.getItem('MyDatabaseKey').then(this.updateState).catch(function(err) {
    console.info(err);
});   
  };

}

Другие вопросы по теме