现在我正在使用reselect
来创建我的选择器,以便从商店中提取数据,并通过props
将其传递给connect
。
为简单起见,我的选择器的结果总是一个JS对象(在选择器的末尾调用toJS()
),如下所示:
const selector = state => state.get('data').toJS();
现在我正在尝试提高性能,我意识到shouldComponentUpdate
浅层比较失去了不变性的优势,因为我从选择器返回的方式。
另一方面,在我的html中使用.get('prop')
似乎非常烦人:
<div>{this.props.data.get('prop')}</div>
特别是如果我有一个将简单的JS对象传递给可变的子组件的情况,如下所示:
<ChildComponent totalItems={10} />
然后在访问道具时没有一致性(有些是可变的,有些是不可变的)。
我想过创建一个帮助器unwrap
函数,如下所示:
const unwrap = obj => obj && obj.toJS ? obj.toJS() : obj;
但我真的不喜欢这个解决方案..我真的不喜欢这些方法。
你用什么清洁代码和&amp;性能
答案 0 :(得分:2)
要将props传递给组件,请将键下的所有数据收集为不可变。
<MyComponent propsKey={Immutable.fromJS({someData: {key: "value"}})} />
要使用Immutable的好处,你应该避免使用toJS()。它非常昂贵,你不能使用有用的不可变函数。在达到&#34; value&#34;之前,您应该使用Immutable.get()。一开始很讨厌,但是,你可以及时看到它是如何有用和易于使用的。 (使用getIn()获取内部键可能比链获取函数更烦人)。通过这种方式,您的代码可以更高效地工作,并且您不需要使用展开函数,在您的组件中,您可以保证this.props.propsKey下的数据始终是不可变的。
答案 1 :(得分:1)
你应该将你的表示组件包装在一个简单的高阶组件中,该组件在传递给它的任何Immutable.js对象道具上调用toJS()
。
这将为您提供最佳平衡,保持Immutable.js的性能优势,同时防止容器组件重新渲染太多,同时保持您的表示组件无依赖性,因此易于重用和可测试。
Redux文档可以选择best practises for using Immutable.js,特别是when not to use .toJS()
,why your presentational components should be kept pure和how a "toJS" higher-order component might be defined and used。
答案 2 :(得分:0)
一年半后回到我的问题,我自己的回答:
如果可能,始终传递不可变对象。如果它不是不可变的,那就按原样传递它。
我认为性能比代码的漂亮程度要重要得多。
如果某个值是不可变的或可变的,我会按原样传递它,如果不需要,则永远不会调用toJS
。如果它们没有存储在redux存储中,我也不会用fromJS
包装可变值。
我只需要知道子组件内部的一些道具是不可变的而有些道具是不可变的 - 而且它实际上非常简单,因为几乎总是复杂的对象是不可变的。