React Parent Component不重新渲染

时间:2018-04-09 16:38:51

标签: reactjs parent-child rerender

我有一个父组件,它呈现从API(正常运行)中引入的子列表。每个孩子都可以选择删除自己。当一个孩子自己删除时,我无法让父母重新渲染。我在这里阅读了大约50个与此主题相关的答案,并尝试了所有这些答案,似乎没有任何工作。我错过了一些东西而且卡住了。

该组件已将redux连接到它,但我已尝试使用和不使用redux连接的代码。我也在回调中尝试了this.forceUpdate(),这也行不通(我在下面的示例代码中对它进行了评论)。

class Parent extends React.Component {
  constructor(props) {
    super(props)
    this.refresh = this.refresh.bind(this)
    this.state = {
      refresh: false,
    }
  }

  componentDidMount(){
    this.getChildren()
  }

  refresh = () => {
    console.log("State: ", this.state)
    this.setState({ refresh: !this.state.refresh })
    // this.forceUpdate();
    console.log("new state: ", this.state)
  }

  getChildren = () => {
    axios.get(
      config.api_url + `/api/children?page=${this.state.page}`,
      {headers: {token: ls('token')}
      }).then(resp => {
         this.setState({
           children: this.state.children.concat(resp.data.children)
           )}
         })
    }

  render(){
    return (

        <div>
             {_.map(this.state.children, (chidlren,i) =>
                <Children
                  key={i}
                  children={children}
                  refresh={() => this.refresh()}
                />
              )}
         </div>
    )
  }
}

然后在我的Children组件中,它完全正常,并且删除按钮成功删除了数据库中的记录,我有以下摘录:

  deleteChild = (e) => {
    e.preventDefault();
    axios.delete(
      config.api_url + `/api/children/${this.state.child.id}`,
      {headers: {token: ls('token')}}
    ).then(resp => {
      console.log("The response is: ", resp);
    })
    this.props.refresh();
    }

render() {
   return(
      <button class="btn" onClick={this.deleteChild}>Delete</button>
  )}
}

我确信我遗漏了一些简单或基本的东西,但我找不到它。

2 个答案:

答案 0 :(得分:1)

您的父渲染方法仅取决于您的删除事件中未更改的this.state.children。将子id传递给this.props.refresh方法,如this.props.refresh(this.state.child.id),并在refresh方法中更新this.state.children,或者在删除后再次调用get children方法发生

子项中删除方法的代码

this.props.refresh(this.state.child.id)

父刷新方法的代码

refresh = (childIdToBeDeleted) => {
    console.log("State: ", this.state)
    this.setState({ refresh: !this.state.refresh })
    // this.forceUpdate();
    console.log("new state: ", this.state)

    //New code
    this.setState({children: this.state.children.filter(child => child.id !== childIdToBeDeleted);
  }

答案 1 :(得分:0)

关于代码的几点注意事项。首先从db中删除然后重新加载可能会很慢并且不是最佳解决方案。也许可以考虑添加remove()函数,该函数可以传递给子组件以更快地更新状态 其次,如果你想调用依赖于先前状态的setState,最好使用这样的回调方法(但我认为你还需要其他东西见下文)

this.setState((prevState,prevProps) => 
   {children: prevState.children.concat(resp.data.children)})  

最后,我认为问题是什么。你实际上并没有从getChildren方法调用refresh所以状态没有更新,如果你想从db重新加载整个状态你不应该连接但只是像这样设置

.then(resp => {
  this.setState({children: resp.data.children})
}

希望它有所帮助。

编辑: 正如评论中所提到的,来自儿童的refresh来电应该是承诺then