1

我有一个父组件,它呈现从 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>
  )}
}

我确定我缺少一些简单或基本的东西,但我找不到它。

4

2 回答 2

1

您的父渲染方法仅取决于 this.state.children 在您的删除事件中没有更改。将子 ID 传递给您的 this.props.refresh 方法,例如 this.props.refresh(this.state.child.id) 并在刷新方法中更新 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);
  }
于 2018-04-09T17:13:55.500 回答
0

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

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

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

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

希望能帮助到你。

编辑:正如评论中提到的,refresh来自孩子的电话应该是承诺的then

于 2018-04-09T17:03:50.697 回答