【问题标题】:How to compare prevProps with this.props in shouldComponentUpdate如何在 shouldComponentUpdate 中比较 prevProps 和 this.props
【发布时间】:2016-08-13 02:50:20
【问题描述】:

我现在使用shouldComponentUpdate,但我不能简单地使用prevProps.myPropObj == this.state.props.myPropObj 进行比较。这是一个对象,我需要进行深入比较。反应是否会向我展示一些方法来告诉我我的道具是否改变了?还是他们希望我自己进行深度比较?我在想 react 专门研究这种比较,所以它应该告诉我们是否相同或不同的真/假?

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    如果 props 是不可变的,你可以使用 react 的shallowCompare。如果您使用 immutablejs 之类的东西,或者您通过替换而不是改变对象来更改对象,则 props 可以是不可变的,例如 const prop = Object.assign({}, prop, { changedValues: 'value' });

    var shallowCompare = require('react-addons-shallow-compare');
    export class SampleComponent extends React.Component {
      shouldComponentUpdate(nextProps, nextState) {
        return shallowCompare(this, nextProps, nextState);
      }
    
      render() {
        return <div className={this.props.className}>foo</div>;
      }
    }
    

    对于非es6、非node环境:

    var shallowCompare = require('react-addons-shallow-compare'); 的等价物是 var shallowCompare = React.addons.shallowCompare;,所以完整的例子是:

    var SampleComponent = React.createClass({
      shouldComponentUpdate: function(nextProps, nextState) {
         return React.addons.shallowCompare(this, nextProps, nextState);
      },
      render: function() {
         return React.createElement('div', {className:this.props.className}, 'foo');
      }
    });
    

    【讨论】:

    • 浅表示它只检查即时数字/字符串/布尔条目吗?如果它看到一个对象,它会跳过它吗?
    • 它检查道具的直接孩子,如果它们是对象或数组,它只是比较引用。这就是为什么你需要替换而不是改变你的对象和数组道具。
    • 啊完美!我只通过var newObj = JSON.parse(JSON.stringify(this.state.obj)); this.setState({obj:newObj}) 来设置状态,无论我的对象有多深,这是否符合不可变的条件?
    • 是的。您正在创建旧对象的新对象。有新的更好的方法可以做到这一点,但这是合格的。
    • 这是一个完美的解决方案,非常感谢!请您验证我在下面发布的非 es-6 版本,如果正确,请将其添加到您的解决方案中。也请您将我链接到JSON.parse(JSON.stringify(...)) 的替代品,我的打字很多哈哈
    【解决方案2】:

    React 不提供开箱即用的对象的深度比较。

    您可以为此自己构建一些东西。例如,通过向您的对象添加和维护 1 个唯一 ID 来注册更改。

    或者在您的应用程序中始终使用像 immutableJS 这样的库。非常适合具有大型复杂对象的大型复杂应用程序。

    为了确保:对于您应用的功能,您不需要shouldComponentUpdate()。 React 有自己的引擎,只呈现状态之间的差异。

    【讨论】:

    • 感谢您的见解,它给了我一些问题来帮助我更多地理解 React。这里的最后一句话是不是和我们在这个话题中讨论的东西冲突:stackoverflow.com/q/36741540/1828637 - on componentDidUpdate 不断触发?还是即使componentDidUpdate 正在触发,DOM 也永远不会真正更新
    • componentDidUpdate() 在渲染周期后运行,即使渲染没有导致 DOM 更改。如果在一轮中 prop = A: 那么 react 会将组件渲染到 DOM。如果在下一轮 prop 被传递,值仍然 A:react 将运行重新渲染循环(但不会更改 DOM,因为没有任何更改),然后将运行 componentDidUpdate()。如果你实现了shouldComponentUpdate(): 在下一轮react 将首先检查shouldComponentUpdate(),这将返回false。然后渲染周期中止,componentDidUpdate() 将不会运行。
    • 哎呀我离开了一会儿,回来看看那个答案,比你好多了!因此,我不确定您在上述解决方案中的最后一句话是什么意思。您提到不应需要shouldComponentUpdate。这是否意味着不需要componentDidUpdate,并且只有当我使用componentDidUpdate 时,我才必须使用shouldComponentUpdate 或其他东西来检查它是否真的改变了?感谢您的耐心解释。我喜欢 React 只是想理解它。
    • 我的意思是,包括shouldComponentUpdate()在内的代码的输出应该与没有该方法的代码的输出完全相同。 shouldComponentUpdate() 用于更快的输出,而不是用于不同的输出。对于componentDidUpdate(),也许this post 会澄清。
    • shallowCompare() 是合适的方法吗?这取决于你的对象。请参阅@OriDori 的回答。 componentDidUpdate() 是比较合适的地方吗?那是另一个问题。答案取决于您希望代码对比较结果做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2020-09-06
    相关资源
    最近更新 更多