【问题标题】:How to re-render the parent component when the child component adds an element to the database?子组件向数据库添加元素时如何重新渲染父组件?
【发布时间】:2021-04-25 00:36:23
【问题描述】:

我有两个组件“父”和“子”。在“父”组件中,我使用“axios”获得了一个元素数组。 “子”组件是一个“模态”,它有一个输入和一个发送按钮,用于向数组中添加一个元素。

获取项目并将它们添加到数据库中工作正常。我使用的数据库是MongoDB,后端有node和express。

当我使用“子”组件添加新元素时,如何让“父”组件呈现?目前,当使用“子”组件添加新元素时,数据库会更新但“父”组件没有。当我刷新页面时,父组件会更新,然后它会从数据库中呈现更新后的表。

Component Parent (main fragment):

class ShoppingList extends Component {
constructor(props){
    super(props)
    this.state = {
        items: []
    }
}

componentDidMount(){
    this.getPosts();
}

getPosts(){
    axios.get('/api/items')
        .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
        .catch(err=>console.log(err))
}

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    会这样做:在数据更新时通知父级,并在收到此通知时强制父级重新渲染:

    父.js

    class ShoppingList extends Component {
    constructor(props){
        super(props)
        this.state = {
            items: []
        }
    }
    
    componentDidMount(){
        this.getPosts();
    }
    
    getPosts(){
        axios.get('/api/items')
            .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
            .catch(err=>console.log(err))
    }
    
    return (
            <Child notifyParent={() => this.forceUpdate()} />
    );
    }
    

    Child.js

    class Child extends Component {
        updatePost() {
            axios.post('...', something)
            .then(resp => {
                //...
                this.props.notifyParent();
            });
        }
    }
    

    【讨论】:

    • 以这种方式放入forceUpdate()会导致错误Maximum update depth exceeded。有什么建议吗? :-)
    • 对不起,我的拼写错误(调用一个函数,而不是仅仅将它从父级传递给子级)。我已经编辑了我的答案,试试这样。
    • 让我告诉你一件有趣的事情。我做了你写的一切。父级不会重新渲染。我将“this.forceUpdate”函数放在“console.log”中,并在向数组添加元素时得到“(callback) {this.updater.enqueueForceUpdate (this, callback, 'forceUpdate');}”。在“子”组件中,它正确地通过了所有“然后”。
    • 如果它工作正常,请将 asnwer 标记为正确 :)
    • 尽可能多地阅读我的最后一条评论 :-) 无法渲染“父”组件我的代码:父:... this.forceUpdate}/ > ...子项: ... axios.post('/api/items',newItem).then(res=>console.log(res.data)).then(()=> this.props.addPost( )).catch(err=>console.log(err)) ...
    【解决方案2】:

    如您所知,预渲染会导致状态更改或道具。

    在“父”组件中,我向状态添加了“update: false”。 我创建了“myForceUpdate”函数,在其中更改了“update:true”状态 将“myFirceUpdate”函数传递给“子”组件。在“child”组件中,我将“props”放入“then”。

    向数组添加元素时,“父”组件中的“myForceUpdate”函数启动并更改“父”组件的状态,但不会重新渲染。

    我做错了什么?

    Parent:                                                                           
    class ShoppingList extends Component {
     constructor(props){
        super(props)
        this.state = {
            items: [],
            update: false
        }
    }
    
    componentDidMount(){
        this.getPosts();
        this.setState({
            update: true
        })
        console.log('CDM')
    }
    
    getPosts(){
        axios.get('/api/items')
            .then(res=>{const arrayItems = res.data;this.setState({items: arrayItems})})
            .catch(err=>console.log(err))
    }
    
    onDeleteClick = (id) => {
        axios.delete(`/api/items/${id}`)
            .then(()=>{this.setState({items: this.state.items.filter(item=>item._id!==id)})})
            .catch(err=>console.log(err)) 
    }
    
    myForceUpdate = () => {
        console.log('myForceUpdate')
        this.setState({
            update: true
        })
        console.log(this.state.update)
    }
    
    render(){
        return(
            <Container>
                <ItemModal addPost={this.myForceUpdate}/>
    
    Child:
    axios.post('/api/items',newItem)
           .then(res=>console.log(res.data))
           .then(()=>this.props.addPost())
           .catch(err=>console.log(err))
    

    【讨论】:

      【解决方案3】:

      通过使用componentDidMount和componentDidUpdate得到了上述问题的解决方案。

      Parent:
      ...
      constructor(props){
              super(props)
              this.state = {
                  items: [],
                  update: false
              }
          }
      
          componentDidMount(){
              this.getPosts();
          }
      
          componentDidUpdate(){
             if(this.state.update === true){
                  this.getPosts();
                  this.setState({
                      update: false
                  })
              }
          }
      ...
      myForceUpdate = () => {
              this.setState({
                  update: true
              })
          }
      
          render(){
              return(
                  <Container>
                      <ItemModal addPost={this.myForceUpdate}/>
      ...
      
      Child:
      ...
      axios.post('/api/items',newItem)
             .then(()=>this.props.addPost())
             .catch(err=>console.log(err))                                                
      ...
      

      【讨论】:

        猜你喜欢
        • 2018-08-12
        • 2019-06-01
        • 1970-01-01
        • 2020-02-13
        • 2021-12-01
        • 2023-02-26
        • 1970-01-01
        • 1970-01-01
        • 2018-10-07
        相关资源
        最近更新 更多