Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/412.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应-什么';在添加新元素后刷新数据列表的最佳做法是什么?_Javascript_Reactjs - Fatal编程技术网

Javascript 反应-什么';在添加新元素后刷新数据列表的最佳做法是什么?

Javascript 反应-什么';在添加新元素后刷新数据列表的最佳做法是什么?,javascript,reactjs,Javascript,Reactjs,我正在建立一个简单的待办事项列表。我有一个用于添加新todo列表项的表单,它下面列出了todo列表中的所有项。通过表单添加新项时,我希望刷新现有待办事项列表项的列表 Items.jsx: class Items extends React.Component { constructor(props) { super(props); this.state = { items: [], loading: tru

我正在建立一个简单的待办事项列表。我有一个用于添加新todo列表项的表单,它下面列出了todo列表中的所有项。通过表单添加新项时,我希望刷新现有待办事项列表项的列表

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
类项扩展React.Component{
建造师(道具){
超级(道具);
此.state={
项目:[],
加载:正确
};
}
componentDidMount(){
get(“/api/v1/items”)
。然后(响应=>{
this.setState({items:response.data,load:false});
});
console.log('state.items:'+this.state.items);
}
componentDidUpdate(){
get(“/api/v1/items”)
。然后(响应=>{
this.setState({items:response.data,load:false});
});
console.log('componentDidUpdate:'+this.state.items);
}
render(){
返回(
{
this.state.items.map(item=>{
返回
})
}
);
}
}
导出默认项
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;
类应用程序扩展组件{
构造函数(){
超级();
此.state={
项目\u消息:“”
}
this.handleInputChange=this.handleInputChange.bind(this);
}
handleSubmit(e){
e、 预防默认值();
console.log(this.state.item_msg);
axios.post(“/api/v1/items”{
项目:this.state.item_msg
})
.然后(功能(响应){
控制台日志(响应);
})
.catch(函数(错误){
console.log(错误);
});
}
handleInputChange(e){
this.setState({item_msg:e.target.value});
console.log('item_msg:'+this.state.item_msg);
}
render(){
返回(
);
}
}
导出默认应用程序;
我在
Items.jsx
文件中添加了
componentdiddupdate
——当我添加一个新的todo列表时,这个新的todo确实会立即显示在列表中——这很酷。然而,我并不认为这是最好的做法。 当我查看JS控制台时,我看到有数百个
组件didUpdate:


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

这是
ReactJS
新手最具挑战性的部分之一。 您不应该在每个级别都创建有状态组件

为状态选择一个公共所有者。在您的情况下,
Items
组件无法在没有来自父
App
组件的数据的情况下自行更改其状态,因此没有理由将状态保留在此位置

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

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

此外,您应该在每次输入更改时更新家长的
App
状态

有两种方法:

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

  • 只需将其设置为不可控制状态,而不将其保持在任何状态,父级将从
    event.target.value
    获取此参数。(现在是这样)

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

    render() {
        const { items, isLoading } = this.state;
    
        return (
          ...
          <Items items={items} isLoading={isLoading} />
          ...
        )
    }
    
    例如: 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) });
    }
    
    最后,只需将数据传递到
    项中

    render() {
        const { items, isLoading } = this.state;
    
        return (
          ...
          <Items items={items} isLoading={isLoading} />
          ...
        )
    }
    
    render(){
    const{items,isLoading}=this.state;
    返回(
    ...
    ...
    )
    }
    
    如果你还没有读过这篇文章,我建议你读一读


    希望有帮助。

    如果没有条件检查,您不应该使用componentDidUpdate,否则它将导致无限循环或重新呈现和API调用,因为componentDidUpdate中的setState可以在
    应用程序
    组件中存储
    项,然后将其传递到
    项目的道具中
    组件-这种方法有点难看,所以很多人使用Redux/Relay来存储全局数据,难道你不能将新项目添加到列表中,而不是获取完整的列表吗?