React-在其中添加新元素后刷新数据列表的最佳实践是什么? [英] React - What's the best practice to refresh a list of data after adding a new element there?

查看:36
本文介绍了React-在其中添加新元素后刷新数据列表的最佳实践是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个简单的待办事项清单.我有一个用于添加新的待办事项列表项的表单,在该表单下列出了待办事项列表中的所有项.通过表单添加新项目时,我想刷新现有待办事项列表项目的列表.

Items.jsx:

  class Items扩展了React.Component {构造函数(道具){超级(道具);this.state = {项目: [],载入中: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);}使成为() {返回 (< ItemSE.Group>{this.state.items.map(item => {返回< Item key = {item.id} data = {item}/>})}</ItemSE.Group>);}}导出默认项目 

App.jsx:

  class App扩展了组件{构造函数(){极好的();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',{项目:this.state.item_msg}).then(function(response){console.log(response);}).catch(函数(错误){console.log(错误);});}handleInputChange(e){this.setState({item_msg:e.target.value});console.log('item_msg:'+ this.state.item_msg);}使成为() {返回 (< div className ="App">< MainHeaderr/><容器>< NewItemFormsend_form = {this.handleSubmit.bind(this)}onInputChange = {this.handleInputChange}typed = {this.state.item_msg}/><项目/></容器></div>);}}导出默认应用程序; 

我在 Items.jsx 文件中添加了 componentDidUpdate -当我添加新的待办事项列表时,这个新的待办事项确实会立即显示在列表中-太酷了.但是,我并不是真的认为这是最佳做法.当我查看JS控制台时,看到数百个 componentDidUpdate:.

因此,刷新待办事项列表的最佳方法是什么?

解决方案

对于刚进入 ReactJS 的新手来说,这是最具挑战性的部分之一.您不应该在每个级别上构成有状态的组件.

选择国家的共同所有者.在您的情况下,没有父 App 组件的数据, Items 组件无法自行更改其状态,因此没有理由将状态保持在该位置.

基本上,应该将 items 数组和 isLoading 标志保留在 App 组件中,然后将其传递到 Items 作为道具.

然后,您可以通过在后端添加新项之后重新获取数据来更新列表,也可以只将其添加到列表中.

此外,您应该在每次输入更改时更新父级的 App 状态.

有两种方法:

  1. 您可以将其保持为 NewItemForm 状态,然后将onSubmit作为函数prop传递给父事件处理程序.

  2. 仅使其变得不可控制并且根本不保持其状态,父级将从 event.target.value 中获取此参数.(现在).

在两种情况下,它都不会每次都重新呈现您的列表.因此,您应该从 App 组件中省略 handleInputChange .

例如: App.js

  constructor(props){超级(道具);//初始状态this.state = {项目: [],isLoading:否,}}handleSubmit(e){e.preventDefault();const {value} = e.target;this.setState({isLoading:true});axios.post('/api/v1/items',{项目:价值}).then(response => {//有几种方法-选择其中一种//1.如果服务器返回您创建的项目//您只需将此项目添加到列表中this.setState(prevState => {返回 {项目:[... prevState.items,response.data],isLoading:否,}});//2.但是如果有任何用户可以与您同时进行更改//(如果不是-只是想像一下:))-最好从服务器重新获取数据axios.get('/api/v1/items').then(response => {this.setState(prevState =>({项目:response.data,isLoading:false});}).catch(err => {console.log('发生了不好的事情:',err)});} 

最后,只需将数据传递到您的 Items 组件中即可.

  render(){const {items,isLoading} = this.state;返回 (...< Items items = {items} isLoading = {isLoading}/>...)} 

如果您尚未阅读本文,我建议您阅读本文- https://reactjs.org/docs/thinking-in-react.html .

希望有帮助.

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:

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;

I added componentDidUpdate to the Items.jsx file - 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:.

Thus, what's the best way to refresh a list to todos?

解决方案

This is one of the most challenging part for the newcomers into ReactJS. You should not make stateful components at the every level.

Choose a common owner for the state. In your case Items component can't change it's state by itself without data from the parent App component, so there are no reasons to keep the state in this place.

Basically, you should keep items array and isLoading flag in the App component and then simply pass it into the Items as a prop.

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 App state on every input changes.

There are two ways:

  1. You can keep it in NewItemForm state 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).

In both cases it won't re-render your list every time. Because of this you should omit the handleInputChange from App component.

For example: 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 Items component.

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.

Hope it helps.

这篇关于React-在其中添加新元素后刷新数据列表的最佳实践是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆