我正在构建一个简单的待办事项列表。我有一个用于添加新的待办事项列表项的表单,在它下面列出了待办事项列表中的所有项目。当我通过表单添加新项目时,我想刷新现有待办事项列表。
项目.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
应用程序.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:
。
因此,将列表刷新为待办事项的最佳方式是什么?
最佳答案
对于 ReactJS
的新手来说,这是最具挑战性的部分之一。
你不应该在每一层都制作有状态的组件。
为状态选择一个共同的所有者。在您的情况下,如果没有来自父 App
组件的数据,Items
组件无法自行更改其状态,因此没有理由将状态保留在此处。
基本上,您应该在 App
组件中保留 items
数组和 isLoading
标志,然后将其简单地传递到 Items
作为 Prop 。
然后,您可以通过在后端添加新项目后重新获取数据或直接将其添加到列表中来更新您的列表。
此外,您应该在每次输入更改时更新父级的 App
状态。
有两种方式:
您可以将其保持在
NewItemForm
状态,然后将 onSubmit 作为函数属性传递给父事件处理程序。只是让它无法控制并且根本不保持状态,父级将从
event.target.value
中获取此参数。 (就像现在一样)。
在这两种情况下,它不会每次都重新呈现您的列表。
因此,您应该从 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 .
希望对您有所帮助。
关于javascript - React - 在添加新元素后刷新数据列表的最佳做法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49378949/