我正在建立一个简单的待办事项清单。我有一个用于添加新的待办事项列表项的表单,在该表单下列出了待办事项列表中的所有项。通过表单添加新项目时,我想刷新现有待办事项列表项目的列表。
Items.jsx:
class Items extends React.Component { constructor(props) { super(props); this.state = { items: [], loading: true }; } componentDidMount() { axios.get('/api/v1/items') .then(response => { this.setState({ items: response.data, loading: false }); }); console.log('state.items: '+this.state.items); } componentDidUpdate() { axios.get('/api/v1/items') .then(response => { this.setState({ items: response.data, loading: false }); }); console.log('componentDidUpdate: '+this.state.items); } render() { return ( <ItemSE.Group> { this.state.items.map(item => { return <Item key={item.id} data={item} /> }) } </ItemSE.Group> ); } } export default Items
App.jsx:
class App extends Component { constructor () { super(); this.state = { item_msg: '' } this.handleInputChange = this.handleInputChange.bind(this); } handleSubmit(e){ e.preventDefault(); console.log(this.state.item_msg); axios.post('/api/v1/items', { item: this.state.item_msg }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); } handleInputChange(e) { this.setState({ item_msg: e.target.value }); console.log('item_msg: '+this.state.item_msg); } render() { return ( <div className="App"> <MainHeaderr /> <Container> <NewItemForm send_form={this.handleSubmit.bind(this)} onInputChange={this.handleInputChange} typed={this.state.item_msg} /> <Items /> </Container> </div> ); } } export default App;
我添加componentDidUpdate到Items.jsx文件中-当我添加新的待办事项列表时,这个新的待办事项确实会立即显示在列表中- 很酷。但是,我并不是真的认为这是最佳做法。当我看着JS控制台时,看到了数百个componentDidUpdate:。
componentDidUpdate
Items.jsx
componentDidUpdate:
因此,刷新待办事项列表的最佳方法是什么?
对于新手来说,这是最具挑战性的部分之一ReactJS。您不应该在每个级别上创建有状态组件。
ReactJS
选择州的共同所有者。在您的情况下Items,没有上级App组件的数据,组件本身无法更改其状态,因此没有理由将状态保持在该位置。
Items
App
基本上,您应该将items数组和isLoading标志保留在App组件中,然后将其Items作为道具简单地传递给。
items
isLoading
然后,您可以通过在后端添加新项后重新获取数据来更新列表,也可以将其添加到列表中。
另外,您应该App在每次输入更改时更新父级的状态。
有两种方法:
您可以使其保持NewItemForm状态,然后将onSubmit作为函数prop传递到父事件处理程序中。
NewItemForm
只是使其不可控制,根本不要保持它的状态,父级将继承此参数event.target.value。(现在)。
event.target.value
在两种情况下,它都不会每次都重新呈现您的列表。因此,您应该省略handleInputChangefrom App组件。
handleInputChange
例如: App.js
constructor(props) { super(props); // Initial state this.state = { items: [], isLoading: false, } } handleSubmit(e){ e.preventDefault(); const { value } = e.target; this.setState({ isLoading: true }); axios.post('/api/v1/items', { item: value }) .then(response => { // there are several ways - choose ONE of them // 1. If server returns you the created item // you can just add this item into the list this.setState(prevState => { return { items: [...prevState.items, response.data], isLoading: false, } }); // 2. But if there are any users who can make changing simultaneously with you // (if not - just imagine it :) ) - it's better to make re-fetch data from server axios.get('/api/v1/items') .then(response => { this.setState(prevState => ({ items: response.data, isLoading: false }); }) .catch(err => { console.log('Something bad is happened:', err) }); }
最后,只需将数据传递到您的Items组件中即可。
render() { const { items, isLoading } = this.state; return ( ... <Items items={items} isLoading={isLoading} /> ... ) }
如果您尚未阅读本文,建议您阅读这篇文章-https: //reactjs.org/docs/thinking-in- react.html。
希望能帮助到你。