Syd*_*ney 3 javascript reactjs redux
这是我在实际应用中遇到的问题的简单复制。 https://jsfiddle.net/zqb7mf61/
基本上,如果您单击“更新待办事项”按钮,文本将从“Clean Room”更改为“Get Milk”。“Clean Room”是reducer 初始状态中的一个值。然后在我的 React 组件中,我实际上尝试克隆状态并变异克隆以将值更改为“获取牛奶”(第 35/36 行)。令人惊讶的是,即使我尝试不对其进行变异,初始状态本身也发生了变异(如第 13 行所示) .
我想知道为什么 Object.assign 不适用于 redux。
这是来自 jsFiddle 的代码。
还原
const initState = {
task: {id: 1, text: 'Clean Room'}
}
// REDUCER
function todoReducer (state = initState, action) {
switch (action.type) {
case 'UPDATE_TODO':
console.log(state)
let newTodo = Object.assign({}, state) // here i'm trying to not make any changes. But i am surpise that state is already mutated.
return newTodo
default:
return state;
}
}
// ACTION CREATORS:
function updateTodo () {
return {type: 'UPDATE_TODO'};
}
// Create Store
var todoStore = Redux.createStore(todoReducer);
Run Code Online (Sandbox Code Playgroud)
反应组件
//REACT COMPONENT
class App extends React.Component{
_onSubmit = (e)=> {
e.preventDefault();
let newTodos = Object.assign({}, this.props.todos) // here i clone the redux state so that it will not be mutated, but i am surprise that it is mutated and affected the reducer.
newTodos.task.text = 'Get Milk'
console.log(this.props.todos)
this.props.updateTodo();
}
render(){
return (
<div>
<h3>Todo List:</h3>
<p> {this.props.todos.task.text} </p>
<form onSubmit={this._onSubmit} ref='form'>
<input type='submit' value='Update Todo' />
</form>
</div>
);
}
}
// Map state and dispatch to props
function mapStateToProps (state) {
return {
todos: state
};
}
function mapDispatchToProps (dispatch) {
return Redux.bindActionCreators({
updateTodo: updateTodo
}, dispatch);
}
// CONNECT TO REDUX STORE
var AppContainer = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(App);
Run Code Online (Sandbox Code Playgroud)
您Object.assign在减速器和组件中都使用。此函数仅复制对象内的第一级变量。您将获得一个新的主对象,但对第二深度对象的引用仍然相同。
例如,您只需复制对task周围对象的引用,而不是实际创建新task对象。
除此之外,最好不要将整个状态加载到您的组件中并以不同的方式处理操作。让我们暂时解决这个问题。您必须在您的对象中创建一个新的任务对象,onSubmit而不是将新文本分配给对象引用。这看起来像这样:
newTodos.task = Object.assign({}, newTodos.task, {text: 'Get Milk'})
Run Code Online (Sandbox Code Playgroud)
此外,要实际更新商店,您必须编辑减速器,因为您现在将当前状态分配给新状态。这个新行看起来像这样:
let newTodo = Object.assign({}, action.todos)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
852 次 |
| 最近记录: |