У меня есть приложение, которое вызывает две функции; Моя корзина и Мои товары. Я пытаюсь сделать так, чтобы при вызове кнопки, отображаемой в MyItems, вызывался метод внутри основного компонента приложения (родительского) и изменялось состояние, но по какой-то причине он не менял значение в диапазоне MyCart.
Мой код ниже - это то, что я пытаюсь сделать, но он не работает, и я не могу понять, почему.
class ShopRemake extends React.Component {
constructor() {
super();
this.state = {
total: 0
}
this.changeTotal = this.changeTotal.bind(this);
}
changeTotal() {
this.setState(prevState => {total: ++prevState.total});
console.info(this.state);
}
render() {
return (
<React.Fragment>
<MyItem changeTotal = {this.changeTotal}/>
<MyCart total = {this.state.total}/>
</React.Fragment>
);
}
}
function MyItem(props) {
return (
<button onClick = {props.changeTotal}> Click Me </button>
);
}
function MyCart(props) {
return (
<span> Total Items: {props.total} </span>
);
}
Я хочу, чтобы после нажатия кнопки диапазон внутри MyCart обновлялся соответствующим образом.



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


Вы должны заключить литерал возвращаемого объекта в круглые скобки в своих стрелочных функциях. В противном случае фигурные скобки будут считаться обозначением тела функции. Следующие работы:
p => ({ foo: 'bar' })
Итак, вызов setState в changeTotal:
changeTotal() {
this.setState(prevState => {total: ++prevState.total});
console.info(this.state);
}
Следует заменить следующим:
changeTotal() {
this.setState(prevState => ({total: ++prevState.total}));
console.info(this.state);
}
Кроме того, setState является асинхронным, вам нужно либо дождаться его (не рекомендуется), либо использовать обратный вызов в качестве второго параметра, чтобы увидеть результирующее состояние:
changeTotal() {
this.setState(
prevState => ({total: ++prevState.total}),
() => { console.info(this.state) }
);
}
РЕДАКТИРОВАТЬ :
Обратите внимание: два приведенных ниже компонента в вашем коде могут быть преобразованы в функции стрелок для получения точно такого же результата, но при этом их будет легче читать:
const MyItem = ({ changeTotal }) => <button onClick = {changeTotal}> Click Me </button>
const MyCart = ({ total }) => <span> Total Items: {total} </span>
И вы также можете преобразовать changeTotal в функцию стрелки, чтобы избежать необходимости привязывать ее в своем конструкторе.
Это потому, что JS будет рассматривать скобки: {} после объявления функции как блоки инструкций, а не объект JSON. С помощью скобок вы сообщаете своему браузеру, что это объект. Рад, что смог помочь
@Treycos, я думаю, в вашем редактировании есть путаница. MyItem и MyCart уже являются функциями без сохранения состояния в исходном коде. Вы не делаете их безгражданскими, вы просто конвертируете их в стрелочные функции. Это не имеет преимущества в производительности, но легче для глаз.
@HarunAkgün Ой, вы правы, я думал, что видел где-то класс, прежде чем менять их. Так что в основном да, изменение их с классических на стрелочные функции только сделало их более удобными для глаз.
Да, не беспокойтесь, это был просто пример в моем коде, я изменил его соответствующим образом.
Ваш setState не возвращает здесь объект. Попробуйте изменить свой метод changeTotal на этот
changeTotal() {
this.setState(prevState => ({ total: prevState.total + 1 }), () =>
console.info(this.state));
}
Методы setState являются асинхронными, если вы хотите зарегистрировать их значение, сделайте это с помощью обратного вызова.
ага, теперь разобрался. В любом случае, спасибо, но, к сожалению, вы ответили вторым, поэтому я не могу поставить галочку :/
Эй, спасибо, чувак, я понятия не имею, как это работает, но это сработало :D