组件中不必要的额外重新渲染导致删除字段的值

Posted

技术标签:

【中文标题】组件中不必要的额外重新渲染导致删除字段的值【英文标题】:unnecessary extra rerender in component cause removing field's value 【发布时间】:2020-03-01 23:32:33 【问题描述】:

我正在使用 React 和 redux,我有一个场景。我有四个动作,其中一个取决于其他两个。 如果我们有this.props.fetch1()this.props.fetch2()this.props.fetch3(),首先我需要接收this.props.fetch1()this.props.fetch2()的结果,然后使用每个结果的id字段通过redux向服务器发出请求这个:

1.
  this.props.fetch1()
  this.props.fetch2()

2.
  this.props.fetchResult1.id1
  this.props.fetchResult2.id2

3.
  this.props.fetch3(this.props.fetchResult1.id1, this.props.fetchResult1.id2)

4.
  this.props.fetchResult3

5.
  show the list on the page

然后通过使用this.props.fetchResult3 这是一个数组,我正在制作一个列表以在渲染页面时显示在页面上。

问题是因为这个动作是异步的,所以结果还没有准备好使用。我使用shouldComponentUpdate 进行渲染,直到结果准备好,但它阻止状态在其他部分更新,即使我比较状态以更新它也会重新渲染组件,在我的情况下,每次更改都会导致我在页面上重置我的字段值处于状态。(我在提交页面上有 2 个文本输入和一个复选框)

shouldComponentUpdate(nextProps, nextState, nextContext) 
        return !isEqual(nextProps.fetchResult1, this.props.fetchResult1) ||
               !isEqual(nextProps.fetchResult2, this.props.fetchResult2) ||
               !isEqual(nextState.fetchResult2, this.state.fetchResult2)

    


componentDidMount() 
        this.callfetch1fetch2();
    


componentDidUpdate(prevProps, prevState, snapshot) 
        if (prevProps.fetchResult1 === this.props.fetchResult1 && !this.props.fetchResult2) 
            this.callfetch1fetch2();
         else 
            this.callfetch3();
        


我想知道处理这个问题的最佳方法,既可以防止重新渲染,又可以正确更新状态。

提前感谢您的任何建议。

【问题讨论】:

【参考方案1】:

你可以使用:

Promise.all([
  this.props.fetch1(),
  this.props.fetch2()
]).then(response => 
// do something
)

或创建一个函数 async/await

async function getResults() 
   let fetchResult1 = await this.props.fetch1(),
   let fetchResult2 = await this.props.fetch1()

【讨论】:

但是fetch1的结果仍然不可用,我在componentDidMount中调用getResults()【参考方案2】:

在这种情况下使用 Promise。

您的组件将仅在 componentDidMountcomponentDidUpdate 中调用单个 fetchAll(您需要在 componentDidUpdate 中的某些 if 中执行此操作 - 仅当需要从服务器重新加载数据时)。

如果您不需要显示fetchResult1fetchResult2,则仅将fetchResult3 映射到您的组件。

function fetchAll() 
    return (dispatch) => 
        return Promise.all([
            dispatch(fetch1()),
            dispatch(fetch2())
        ]).then(([fetchResult1, fetchResult2]) =>
            dispatch(fetchResult3(fetchResult1.id, fetchResult2.id))
        );
    ;

【讨论】:

但是fetch1的结果仍然不可用,我在componentDidMount中调用fetchAll() 当您的异步数据在组件render 函数中不可用时,您必须处理这种情况。例如:如果还没有必要的数据,请返回nullshouldComponentUpdate 应仅用于性能改进。如果您已将状态正确映射到 props,则只要映射数据发生更改(即异步 action creator 调度 action 和 reducer 更改状态后),组件就会重新渲染。

以上是关于组件中不必要的额外重新渲染导致删除字段的值的主要内容,如果未能解决你的问题,请参考以下文章

JSF2 - 为啥渲染响应不重新渲染组件设置?

在 React 中提升状态不会导致不必要的重新渲染吗?

根据用户输入的值输入字段重新渲染 NgRepeat

当状态改变时,对文本字段做出反应 onChange 更新整个组件

(p)React 避免在提交时不必要的重新渲染

mysql-重新排序修改排序值-删除数据后排序字段序号断层,重新根据顺序设置连续性的排序值