2017-05-26 50 views
1

嘿,我正在嘗試創建一個簡單的待辦事項列表,並添加了必要的組件。但是,狀態不會在標題{this.state.data.length}和TodoList {this.state.data}中更新。一個Codepen和相關的代碼如下。在組件中沒有更新的狀態

https://codepen.io/skasliwal12/pen/BREYXK

const TodoForm = ({addTodo}) => { 
    let input; 
    return (
    <div> 
    <input ref={node => {input = node;}} /> 
    <button onClick={(e) => { 
     e.preventDefault(); 
     addTodo(input.value); 
     input.value=''; 
    }}> + 
    </button> 
    </div> 
); 
}; 

const TodoList = ({todos}) => { 
    let todoNodes = todos.map(todo => { 
     return <li>{todo}</li> 
    }); 
    return <div> {todoNodes} </div>; 
} 

const Title = ({todoCount}) => { 
    return (
    <div> 
     <div> 
     <h1>To-do App {todoCount} items</h1> 
     </div> 
    </div> 
); 
} 

class TestApp extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { data : [] } 
    } 

    addTodo(val) { 
    let todo = {text: val} 
    this.state.data.push(todo); 
    this.setState = ({data: this.state.data}); 
    console.log('state updated?') 
    } 

    render(){ 
    return (
     <div> 
     <Title todoCount={this.state.data.length}/> 
     <TodoForm addTodo={this.addTodo.bind(this)}/> 
     <TodoList todos={this.state.data}/> 
     </div> 
    ); 
    } 
} 

ReactDOM.render(<TestApp />, document.getElementById('root')); 

回答

1

很簡單,像你在這裏做你不變異的狀態是很重要的

this.state.data.push(todo); 

這是很難調試,並增加了副作用,因爲很難保持蹤跡。遵循你的方法,你應該把狀態複製到一個var,更新該var,然後將它作爲你的狀態中的新字段傳遞。哪些可以工作,但這也是我不建議的。一般好的方法是基於對計算新狀態的舊

// this.state.data.push(todo); You can remove this line 
this.setState(prevState => ({ data: prevState.data.concat(todo) })) 

這將使用setState方法解決您的問題,並避免變異的狀態,這是你永遠不應該做的事,只有更新狀態。

我也更新了你的TodoList,這是顯示不正確,你必須訪問todo的text字段才能顯示。

const TodoList = ({todos}) => { 
    let todoNodes = todos.map(todo => { 
     return <li>{todo.text}</li> 
    }); 
    return <div> {todoNodes} </div>; 
} 

https://codepen.io/anon/pen/MmRVmX?editors=1010

+0

甜,感謝您的回答。 –

相關問題