MobX:分配后重新渲染
MobX: rerender after assign
美好的一天!
我有一个父组件:
@observer
class ToDos extends Component {
componentWillMount() {
this.state = new State();
this.onClearAllCompleted = this.onClearAllCompletedHandler.bind(this);
}
onClearAllCompletedHandler() {
this.state.clearAllCompleted();
}
render() {
const todos = this.state.todos;
return (
<Provider todos={todos}>
{this.props.children}
<ClearAllButton onClick={this.onClearAllCompleted} />
</Provider>
);
}
}
并声明class:
class TodosState {
@observable todos = [
{ title: 'Sleep', completed: true },
{ title: 'Sleep more', completed: false },
{ title: 'Sleep more than before', completed: false }
];
@action
clearAllCompleted() {
this.todos = this.todos.filter(todo => !todo.completed);
}
}
当我尝试清除所有已完成的待办事项时,它会在浏览器控制台中清除它们并发出警告:MobX Provider: Provided store 'todos' has changed. Please avoid replacing stores as the change might not propagate to all children
。
在这之后什么都没有发生:我已经渲染旧 html ;(
所以,我认为 childrens 有可观察的 todos 对象,它引用一个对象,在状态分配后我有不同的引用。 Childs 不知道这一点,他们的 observable 根本没有改变。那么,在这种情况下我能做什么?
问题出在 render
方法中 - 在每次重新渲染时,您将新的 todos
传递到 Provider
组件中。 Provider
组件是一个棘手的组件,它总是需要相同的道具,但你每次都传递不同的 todos
数组。
更正代码:将整个 state
对象传递给 Provider
(this.state
对象在您的示例中始终相同,正如 Provider
所希望的那样)
render() {
return (
<Provider store={this.state}>
{this.props.children}
<ClearAllButton onClick={this.onClearAllCompleted} />
</Provider>
);
}
顺便说一下,我建议您将 componentWillMount()
替换为 constructor()
。构造函数是商店初始化的更好地方。特别是在下一版本的 React (16.0+) 中,componentWillMount()
可能会在实际挂载之前为同一个实例调用多次。
美好的一天!
我有一个父组件:
@observer
class ToDos extends Component {
componentWillMount() {
this.state = new State();
this.onClearAllCompleted = this.onClearAllCompletedHandler.bind(this);
}
onClearAllCompletedHandler() {
this.state.clearAllCompleted();
}
render() {
const todos = this.state.todos;
return (
<Provider todos={todos}>
{this.props.children}
<ClearAllButton onClick={this.onClearAllCompleted} />
</Provider>
);
}
}
并声明class:
class TodosState {
@observable todos = [
{ title: 'Sleep', completed: true },
{ title: 'Sleep more', completed: false },
{ title: 'Sleep more than before', completed: false }
];
@action
clearAllCompleted() {
this.todos = this.todos.filter(todo => !todo.completed);
}
}
当我尝试清除所有已完成的待办事项时,它会在浏览器控制台中清除它们并发出警告:MobX Provider: Provided store 'todos' has changed. Please avoid replacing stores as the change might not propagate to all children
。
在这之后什么都没有发生:我已经渲染旧 html ;(
所以,我认为 childrens 有可观察的 todos 对象,它引用一个对象,在状态分配后我有不同的引用。 Childs 不知道这一点,他们的 observable 根本没有改变。那么,在这种情况下我能做什么?
问题出在 render
方法中 - 在每次重新渲染时,您将新的 todos
传递到 Provider
组件中。 Provider
组件是一个棘手的组件,它总是需要相同的道具,但你每次都传递不同的 todos
数组。
更正代码:将整个 state
对象传递给 Provider
(this.state
对象在您的示例中始终相同,正如 Provider
所希望的那样)
render() {
return (
<Provider store={this.state}>
{this.props.children}
<ClearAllButton onClick={this.onClearAllCompleted} />
</Provider>
);
}
顺便说一下,我建议您将 componentWillMount()
替换为 constructor()
。构造函数是商店初始化的更好地方。特别是在下一版本的 React (16.0+) 中,componentWillMount()
可能会在实际挂载之前为同一个实例调用多次。