У меня проблемы с проектом 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);
});Однако это дает мне еще одну ошибку:



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я считаю, что в обещании это неправильно. Вы пробовали заменить функцию (значение) {// код} на значение => // код?
Скорее всего, это связано с лексической областью видимости, которую предоставляют стрелочные функции.
Привет, Джош, спасибо за ваш вклад - только что попробовал, но получаю еще одну ошибку. См. Снимок экрана в обновлении Edit. - TypeError: невозможно прочитать свойство 'map', равное нулю.
Хорошо, вы можете распечатать состояние после вызова функции? Может случиться так, что value, для которого устанавливается state.item, тоже не является массивом
Думаю, проблема в привязке "этого". в вашем обещании. тогда у вас нет «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);
});
};
}
Можете ли вы попробовать инициализировать
stateвconstructor?