[英]React/Redux not triggering child render on state update
我正在學習 React/Redux 並且遇到了卡住的地步。 在示例待辦事項應用程序中,當添加新的待辦事項時,我正在處理 addTodo 操作,我可以逐步執行 store.dispatch 邏輯。 失敗的是 hasStatePropsChanged 值計算為 false 因此沒有子更新。
代碼片段如下:
import React from 'react';
import { connect } from 'react-redux';
import { store, addTodo, completeTodo, deleteTodo, clearTodo } from './TodoState.jsx';
class AddTodoForm extends React.Component {
...
}
class TodoItem extends React.Component {
....
}
let TodoList = ({items}) => (
<ul>
{items.map((item,index) =>
<TodoItem key={index} index={index} message={item.message} completed={item.completed}/>
)}
</ul>
)
let TodoComponent = ({ items, onAddTodo, onCompleteTodo, onDeleteTodo, onClearTodo }) => /* expand's props */
(
<div>
<h1>Todo</h1>
<AddTodoForm onAddTodo={onAddTodo} message/>
<TodoList items={items} onCompleteTodo={onCompleteTodo} onDeleteTodo={onDeleteTodo} onClearTodo={onClearTodo}/>
</div>
)
const mapStateToProps = (state) => {
return {
items: state.todo.items
}
}
const mapDispatchToProps = (dispatch) => {
return {
onAddTodo(message) {
dispatch(addTodo(message))
},
onCompleteTodo(index) {
dispatch(completeTodo(index))
},
onDeleteTodo(index) {
dispatch(deleteTodo(index))
},
onClearTodo(index) {
dispatch(clearTodo(index))
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoComponent);
AddTodoForm 正確調度 addTodo 操作,問題是即使 items 數組是一個新數組,TodoList 組件也不會再次呈現。
更新:我的減速器確實返回了一個新狀態。
這是減速器和動作代碼:
import { createStore } from 'redux';
var defaultState = { todo: { items: [] } }
const ADD_TODO = 1;
const COMPLETE_TODO = 2;
const DELETE_TODO = 3;
const CLEAR_TODO = 4;
const addTodo = (message) => { return {type: ADD_TODO, message: message, completed: false} };
const completeTodo = (index) => { return {type: COMPLETE_TODO, index:index} };
const deleteTodo = (index) => { return {type: DELETE_TODO, index:index} };
const clearTodo = (index) => { return {type: CLEAR_TODO, index:index} };
function todoReducer(state,action) {
switch(action.type) {
case ADD_TODO:
var newState = Object.assign({},state);
newState.todo.items.push({message:action.message,completed:false});
return newState;
case COMPLETE_TODO:
var newState = Object.assign({},state);
newState.todo.items[action.index].completed = true;
return newState;
case DELETE_TODO:
var items = [].concat(state.todo.items);
items.splice(action.index,1);
return Object.assign({},state,{
todo: {
items:items
}
});
case CLEAR_TODO:
return Object.assign({},state,{
todo: {
items: []
}
});
default:
return state;
}
}
var store = createStore(todoReducer,defaultState);
export { store, addTodo, completeTodo, deleteTodo, clearTodo };
謝謝,
亞倫
檢查您是否在減速器中返回了一個新對象作為狀態。 例如: return Object.assign ({}, state, {items: [...oldItems, newItem]})
注意這里[...oldItems, newItem]
這將創建新數組。 在您的情況下, Object.assign 僅執行淺復制,實際上項目已更改但具有相同的引用。 看看工作示例:
import React from 'react';
import { render } from 'react-dom';
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';
var defaultState = { todo: { items: [] } }
const ADD_TODO = 1;
const COMPLETE_TODO = 2;
const DELETE_TODO = 3;
const CLEAR_TODO = 4;
const addTodo = (message) => { return {type: ADD_TODO, message: message, completed: false} };
const completeTodo = (index) => { return {type: COMPLETE_TODO, index:index} };
const deleteTodo = (index) => { return {type: DELETE_TODO, index:index} };
const clearTodo = (index) => { return {type: CLEAR_TODO, index:index} };
function todoReducer(state,action) {
switch(action.type) {
case ADD_TODO:
var newItem = {message:action.message,completed:false};
return Object.assign({},state, {todo: {items: [...state.todo.items, newItem]}});
case COMPLETE_TODO:
var newState = Object.assign({},state);
newState.todo.items[action.index].completed = true;
return newState;
case DELETE_TODO:
var items = [].concat(state.todo.items);
items.splice(action.index,1);
return Object.assign({},state,{
todo: {
items:items
}
});
case CLEAR_TODO:
return Object.assign({},state,{
todo: {
items: []
}
});
default:
return state;
}
}
var store = createStore(todoReducer,defaultState);
class AddTodoForm extends React.Component {
render() {
return <button onClick={this.props.onAddTodo}>test</button>
}
}
class TodoItem extends React.Component {
render() {
return <span>item</span>
}
}
let TodoList = ({items}) => (
<ul>
{items.map((item,index) =>
<TodoItem key={index} index={index} message={item.message} completed={item.completed}/>
)}
</ul>
)
let TodoComponent = ({ items, onAddTodo, onCompleteTodo, onDeleteTodo, onClearTodo }) => /* expand's props */
(
<div>
<h1>Todo</h1>
<AddTodoForm onAddTodo={onAddTodo} message/>
<TodoList items={items} onCompleteTodo={onCompleteTodo} onDeleteTodo={onDeleteTodo} onClearTodo={onClearTodo}/>
</div>
)
const mapStateToProps = (state) => {
return {
items: state.todo.items
}
}
const mapDispatchToProps = (dispatch) => {
return {
onAddTodo(message) {
dispatch(addTodo(message))
},
onCompleteTodo(index) {
dispatch(completeTodo(index))
},
onDeleteTodo(index) {
dispatch(deleteTodo(index))
},
onClearTodo(index) {
dispatch(clearTodo(index))
}
}
}
var Wrapper = connect(mapStateToProps,mapDispatchToProps)(TodoComponent);
render(
<Provider store={store}>
<Wrapper />
</Provider>,
document.getElementById('app')
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.