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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 08:33:40  来源:igfitidea点击:

React - What's the best practice to refresh a list of data after adding a new element there?

javascriptreactjs

提问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:.

我添加componentDidUpdateItems.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:

有两种方式:

  1. You can keep it in NewItemFormstate and then pass onSubmit into the parent event handler as a function prop.

  2. 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).

  1. 您可以将其保持在NewItemForm状态,然后将 onSubmit 作为函数道具传递到父事件处理程序中。

  2. 只需让它无法控制并且根本不要将其保持在 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.

希望能帮助到你。