【问题标题】:How to re-render another component after setState in ReactTable getTdProps onClick event?如何在 ReactTable getTdProps onClick 事件中的 setState 之后重新渲染另一个组件?
【发布时间】:2018-10-16 19:12:02
【问题描述】:

我在一个页面上有两个反应表。第一个显示已保存查询的列表。用户可以单击任何已保存的查询来运行查询结果,这些结果将呈现在第二个表中。我正在尝试根据“showQueryResults”的布尔状态显示/隐藏查询结果表。

当我在 getTDProps onClick 事件处理程序中将 showQueryResults 的状态设置为 false 时,没有任何反应。当我在页面的其他位置放置一个执行完全相同操作的测试按钮时,查询结果表被成功隐藏。

<ReactTable
    data={this.props.data}
    columns={columns}
    getTdProps={(state, rowInfo, column) => {
      return {
        onClick: () => {
          if (rowInfo){
            const row = rowInfo.row
            this.setState({selectedListId: row.id, showQueryResults: false},() => {
                if(column.id !== 'delete'){
                  if (row.search_type === 'dynamic'){
                    this.props.fetchQueryResults(row._original.search_criteria)
                      .then(this.setState({showQueryResults: true}))
                  } else {
                    this.props.fetchStaticResults(row.id)
                      .then(this.setState({showQueryResults: true}))
                  }
                }
              });
          }
        },
    }}}
/> 

在我的主渲染函数中,我有条件地渲染查询结果如下:

{
 this.state.showQueryResults
 ? <ListResults
   queryResults = {this.props.queryResults}
   onModalToggle = {this.handleModalToggle.bind(this)}
   showSave = {false}
   />
   : null
 }

就像我说的,下面的测试按钮成功地隐藏了上面的元素:

<button onClick={() => this.setState({showQueryResults: !this.state.showQueryResults})}>Toggle</button>

有什么想法吗?

编辑:我还尝试了以下方法以确保 fetchQueryResults 在第二个 setState 之前完成(根据 cmets),但这样做完全相同:

      <ReactTable
    data={this.props.data}
    columns={columns}
    getTdProps={(state, rowInfo, column) => {
      return {
        onClick: () => {
          if (rowInfo){

            const row = rowInfo.row

            const handleFetchQuery = (searchCriteria) => {
              return new Promise((resolve)=>{
                let response = this.props.fetchQueryResults(searchCriteria)
                if (response){
                  resolve('Success')
                }

              })
            }

            this.setState({selectedListId: row.id, showQueryResults: false},() => {
                if(column.id !== 'delete'){
                  if (row.search_type === 'dynamic'){
                    handleFetchQuery(row._original.search_criteria)
                      .then(() => {this.setState({showQueryResults: true})})
                  } else {
                    this.props.fetchStaticResults(row.id)
                      .then(this.setState({showQueryResults: true}))
                  }
                }
              });
          }
        },
    }}}

【问题讨论】:

    标签: javascript reactjs promise render react-table


    【解决方案1】:

    在此之后setState

    this.setState({selectedListId: row.id, showQueryResults: false}
    

    你在回调中触发另一个setState

    if(column.id !== 'delete'){
      if (row.search_type === 'dynamic'){
         this.props.fetchQueryResults(row._original.search_criteria)
           .then(this.setState({showQueryResults: true}))
      } else {
         this.props.fetchStaticResults(row.id)
          .then(this.setState({showQueryResults: true}))
      }
    }
    

    所以showQueryResultstrue,那么你的条件在

    {
     this.state.showQueryResults
      ? <ListResults
        queryResults = {this.props.queryResults}
        onModalToggle = {this.handleModalToggle.bind(this)}
        showSave = {false}
       />
       : null
    }
    

    将始终呈现真实条件。这意味着您的表格将始终可见。

    【讨论】:

    • 所以我尝试使用setState({showQueryResults: false}) 隐藏组件,然后获取新结果,并使用setState({showQueryResults: true}) 显示具有新结果的组件。据我所知,我正在原始 setState 回调中获取新结果,然后在重置状态之前等待获取完成。结果需要一些时间才能返回,同时原始结果永远不会隐藏。
    • 我越看这个,我确实认为问题在于第二个 setState 在第一个 setState 之后发生得太快,但我不明白为什么 setState 在 fetchQueryResults 完成之前发生。编辑我的原始回复以显示我尝试过的另一种方式。
    【解决方案2】:

    所以我使用 async/await 以下列方式使其工作:

          <ReactTable
          data={this.props.data}
          columns={columns}
          getTdProps={(state, rowInfo, column) => {
              return {
                onClick: () => {
                  if (rowInfo){
    
                    const row = rowInfo.row
    
                    const handleFetchQuery = async (searchCriteria) => {
                       await this.props.fetchQueryResults(searchCriteria)
                       .then(success => {this.setState({showQueryResults: !this.state.showQueryResults})
                    })}
    
                    const handleFetchStatic = async (listId) => {
                       await this.props.fetchStaticResults(listId)
                       .then(success => {this.setState({showQueryResults: !this.state.showQueryResults})
                    })}
    
                    this.setState({selectedListId: row.id, showQueryResults: false},() => {
                    if(column.id !== 'delete'){
                      if (row.search_type === 'dynamic'){
                          try {
                            handleFetchQuery(row._original.search_criteria)
                          } catch (e) {
                            console.log(e)
                          }
    
                      } else {
                          try {
                            handleFetchStatic(row.id)
                          } catch (e) {
                            console.log(e)
                          }
                    }
                  }
                  });
              }
            },
        }}}
      />
    

    仍然不确定为什么以前的方法不起作用,但我会接受的!希望这对将来的其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-08-08
      • 1970-01-01
      • 2022-11-02
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      相关资源
      最近更新 更多