javascript React - 在那里添加新元素后刷新数据列表的最佳实践是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49378949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React - What's the best practice to refresh a list of data after adding a new element there?
提问by user984621
I am building a simple todo list. I have a form for adding a new todo list item and under it are listed all items in the todo list. When I add a new item through a form, I want to refresh the list of existing todo list items.
我正在构建一个简单的待办事项列表。我有一个用于添加新的待办事项列表项的表单,在它下面列出了待办事项列表中的所有项目。当我通过表单添加新项目时,我想刷新现有待办事项列表项目的列表。
Items.jsx:
项目.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:
应用程序.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;
I added componentDidUpdateto the Items.jsxfile - when I add a new todo list, this new todo will indeed display immediately to the list - that's cool. However, I don't really feel this is the best practice.
When I look to the JS console, I see there hundreds of componentDidUpdate:.
我添加componentDidUpdate到Items.jsx文件中 - 当我添加一个新的待办事项列表时,这个新的待办事项确实会立即显示到列表中 - 这很酷。但是,我真的不认为这是最佳做法。当我查看 JS 控制台时,我看到有数百个componentDidUpdate:.
Thus, what's the best way to refresh a list to todos?
因此,刷新待办事项列表的最佳方法是什么?
回答by Denys Kotsur
This is one of the most challenging part for the newcomers into ReactJS.
You should not make stateful components at the every level.
这对新人来说是最具挑战性的部分之一ReactJS。您不应该在每个级别都制作有状态的组件。
Choose a common owner for the state. In your case Itemscomponent can't change it's state by itself without data from the parent Appcomponent, so there are no reasons to keep the state in this place.
为国家选择一个共同的所有者。在您的情况下,如果Items没有来自父App组件的数据,组件无法自行更改其状态,因此没有理由将状态保留在此位置。
Basically, you should keep itemsarray and isLoadingflag in the Appcomponent and then simply pass it into the Itemsas a prop.
基本上,您应该在组件中保留items数组和isLoading标志App,然后简单地将其Items作为道具传递给 。
Then, you may update your list by re-fetching data after adding new item on the backend or just add it into the list.
然后,您可以通过在后端添加新项目后重新获取数据来更新您的列表,或者只是将其添加到列表中。
Also, you should update parent's Appstate on every input changes.
此外,您应该App在每次输入更改时更新父级的状态。
There are two ways:
有两种方式:
You can keep it in
NewItemFormstate and then pass onSubmit into the parent event handler as a function prop.Just make it uncontrollable and don't keep it in state at all and parent will take this param from
event.target.value. (As it is now).
您可以将其保持在
NewItemForm状态,然后将 onSubmit 作为函数道具传递到父事件处理程序中。只需让它无法控制并且根本不要将其保持在 state 中,父级将从
event.target.value. (就像现在一样)。
In both cases it won't re-render your list every time.
Because of this you should omit the handleInputChangefrom Appcomponent.
在这两种情况下,它都不会每次都重新呈现您的列表。因此,您应该省略handleInputChangefromApp组件。
For example: App.js
例如: 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) });
}
Finally, just pass data it into your Itemscomponent.
最后,只需将数据传递到您的Items组件中即可。
render() {
const { items, isLoading } = this.state;
return (
...
<Items items={items} isLoading={isLoading} />
...
)
}
I advice you to read this article if you haven't read it yet - https://reactjs.org/docs/thinking-in-react.html.
如果您还没有阅读这篇文章,我建议您阅读它 - https://reactjs.org/docs/thinking-in-react.html。
Hope it helps.
希望能帮助到你。

