2017-04-21 50 views
0

美好的一天!MobX:分配後重新排列

我有一個父組件:

@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 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;(

所以,我認爲兒童有一個對象,並在國家分配後的引用我有不同的參考待辦事項觀察的對象童車不知道。這一點,他們觀察到沒有改變過所以,我可以在這種情況下做

回答

1

的問題是render方法 - ?每個重新渲染傳遞新todosProvider組件Provider成分是棘手組件總是需要相同的道具,但每次都會傳遞不同的todos陣列。

更正代碼:通過全state對象爲Providerthis.state對象總是在你的例子一樣,就像Provider希望)

render() { 

    return (
     <Provider store={this.state}> 
     {this.props.children} 
     <ClearAllButton onClick={this.onClearAllCompleted} /> 
     </Provider> 
    ); 
} 

通過我建議你用constructor()更換componentWillMount()的方式。構造函數更適合存儲初始化。特別是在實際安裝之前,可能會在同一實例中多次調用React(16.0+)componentWillMount()的下一個版本。