#javascript #reactjs #react-native #redux #react-redux
#javascript #reactjs #react-native #redux #react-redux
Вопрос:
Я пытаюсь реализовать redux в своем приложении react. До сих пор я создал 4 действия для управления «элементами» моих приложений. Первые три; GET_ITEMS, DELETE_ITEM и ADD_ITEM работают отлично и легко сочетаются с моим существующим приложением react. Четвертый «TOGGLE_ITEM» фактически функционирует и переключает элементы, но каким-то образом сломал мой существующий компонент react. Я получаю неопределенную ошибку «item» в моем Items.js досье. Вот код, строки со звездочками имеют большое значение:
- Корневой компонент = Musiclist.js:
class MusicList extends Component {
componentDidMount() {
this.props.getItems();
*console.log(this.props.item.items)*
// Console log returns the proper items array that gets passed down below to the Items component
}
toggle = (id) => {
*this.props.toggleItem(id)*
// Pings the item reducer and executes the toggle function, which functions properly
}
delItem = (id) => {
this.props.deleteItem(id)
}
addItem = (url) => {
this.props.addItem(url)
}
render() {
*const { items } = this.props.item*
// Same as saying this.props.item.items
return (
<div>
<AddItem addItem={this.addItem}/>
*<Items items = {items} toggle = {this.toggle} delItem = {this.delItem} />*
// Takes in the array items as a prop and the function toggle() as a prop
</div>
)
}
}
MusicList.propTypes = {
getItems: PropTypes.func.isRequired,
deleteItem: PropTypes.func.isRequired,
addItem: PropTypes.func.isRequired,
toggleItem: PropTypes.func.isRequired,
item: PropTypes.object.isRequired
}
const mapStateToProps = (state) => ({
item: state.item
})
export default connect(mapStateToProps, { getItems, deleteItem, addItem, toggleItem})(MusicList);
Редуктор = itemReducer.js:
Кажется, это работает отлично и работает так, как должно. Я также не вижу никаких видимых причин, по которым это повлияло бы на компонент Items, поэтому, скорее всего, это красное слушание… Но у меня начались проблемы только после его реализации.
case TOGGLE_ITEM:
return {
items: state.items.map(item => {
if(item.id === action.payload) {
item.isOpen = !item.isOpen
}
})
}
Проблемный компонент = Items.js:
Компонент выдает ошибку.
import React, { Component } from 'react';
import Item from "./Item";
import PropTypes from "prop-types";
class Items extends Component {
componentDidMount() {
// Console logs the same array as the one in MusicList.js
*console.log(this.props.items)*
this.props.items.map((item) => (
// Console logs as it's supposed to, maps the items and prints them, no "item undefined" error
console.log(item)
))
}
render() {
return this.props.items.map((item) => (
<div>
// "item" is undefined on this line despite the map function defining it above.
// I did not change any code here when implementing redux, yet there was no error before redux.
*<Item key = {item.id} item = {item} toggle = {this.props.toggle} delItem = {this.props.delItem} isOpen = {item.isOpen}/>*
</div>
));
}
}
// PropTypes
Items.propTypes = {
items: PropTypes.array.isRequired
}
export default Items;
Любая помощь приветствуется!
Комментарии:
1. Правильное обновление переключения также должно копировать любое существующее состояние и возвращать новую ссылку на объект item в сопоставлении, т.
return { ...state, item: state.items.map(item => item.id === action.payload ? { ...item, isOpen: !item.isOpen } : item), }
Е.. Поскольку у вас есть проблема только после реализацииTOGGLE_ITEM
, можно ли предположить, что код пользовательского интерфейса в порядке, пока вы не попытаетесь переключить элемент? Можете ли вы предоставить более полный пример кода и шаги воспроизведения? Запущенный codesandbox был бы действительно полезен, чтобы мы могли отладить его в реальном времени.
Ответ №1:
функции map в reducer потребуется оператор return
case TOGGLE_ITEM:
return {
...state,
items: state.items.map(item => {
if(item.id === action.payload) {
item.isOpen = !item.isOpen
}
return item;
})
}
Это решит проблему. И всегда распределяйте состояние, а затем добавляйте запятую, а затем измененные пары ключ-значение
Комментарии:
1. Часть «return item» решила эту проблему. Но какова цель возврата состояния с помощью «… state»?
2. Когда вы используете
...state
(деструктурирование объекта ES6, вы также можете использовать Object.assign) в качестве возврата функции reducer , тогда она создает объект со всеми данными, которые находятся в этом редукторе, а затем упомянутые ключи добавляются / заменяются на этот объект. таким образом, ваши другие данные остаются нетронутыми, но если вы не используете...state
, то ваш редуктор содержит только объект с упомянутыми парами ключ-значение. Ознакомьтесь с этим документом redux.js.org/basics/reducers#handling-actions
Ответ №2:
Хорошо ли это написано в вашем приложении? Эта строка кода должна быть:
<Item key={item.id} item={item} toggle={this.props.toggle} delItem={this.props.delItem} isOpen={item.isOpen}/>
Между реквизитом и фактическим значением не должно быть пробелов
Комментарии:
1. К сожалению, это не сработало, я почти уверен, что пробел либо косметический, либо компилятор исправляет его.