javascript - Redux Reducer 或组件的 ShouldComponentUpdate 中的深度比较?
问题描述
在我的 React Redux 应用程序中,setInterval()
持续调用一个this.props.getLatestNews()
查询 REST API 端点的操作创建器。在获取 API 响应(对象数组)时,它将以响应数组作为有效负载分派一个动作。
反应组件
class Newsfeed extends Component {
constructor(props) {
super(props);
this.state = { ... }
}
componentWillMount() {
this.updateTimer = setInterval(() => { this.props.getLatestNews() }, 1000);
}
componentWillUnmount() {
clearInterval( this.updateTimer );
}
shouldComponentUpdate(nextProps, nextState) {
// Should we do a deep compare of nextProps & this.props,
// shallow compare of nextState & thisState?
}
render() {
return ( ... )
}
}
const mapStateToProps = (state) => ({
newsfeed: state.newsfeed
});
const mapDispatchToProps = (dispatch) => {
return {
getLatestNews: () => dispatch(getLatestNews())
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Newsfeed);
在reducer中,它目前总是更新部分状态,不管有没有变化
减速器
export default function newsfeedReducer(state=initialState, action) {
switch (action.type) {
case NEWSFEED_RECEIVED:
// Or should we do the deep compare of `action.payload` with `state.items` here?
return { ...state, items: action.payload }
default:
return state
}
}
根减速器
...
const rootReducer = combineReducers({
newsfeed: newsfeedReducer
});
...
大多数时候,当收到 API 结果时,Redux 存储中没有不存在的新项目。props
如果 reducer 仍然用 API 结果替换了 store 的这一部分,除非我们在内部进行深度比较,否则连接的组件将由于新的对象引用而重新渲染shouldComponentUpdate()
。
为了避免对 React 组件进行不必要的重新渲染,我正在考虑对shouldComponentMount()
函数中的 current 和 next 属性进行深度比较,或者对应该替换的action.payload
with进行深度比较。state.items
进行深度比较的推荐位置在哪里?或者这根本没有必要?
谢谢!
解决方案
一般来说,我们可以做出一些选择来避免在使用 redux 时重新渲染。
- 在 Reducer 中:比较当前状态和 api/action 有效负载结果,即您的可能/下一个状态。只需在减速器中返回先前的状态,就不会导致重新渲染
- 在组件中:如果您的比较取决于您的组件道具,则使用
shouldComponentUpdate
which 为您提供nextProps
和nextState
作为参数。 - 在 Actions 中:如果您想进行条件调度(即,如果对 api-results 不满意,则调度其他内容)然后在您的操作中进行比较。您可以使用getState访问当前状态。
注意 - 即使您使用 Pure 组件,组件仍会重新渲染,因为即使对象值相同,状态的对象引用也会更改。
第 1 点的演示 -shouldComponentUpdate
第 2 点的演示 -state-reducer-etc
推荐阅读
- machine-learning - 使用 Pytorch 预测舞蹈帧
- r - 如何使用 R 中的文本函数将方程添加到我的绘图中?
- json - 如何以模块化形式在 Terraform 中使用 s3 生命周期规则,即在单独的 JSON 中引用?
- android - 如何从 kotlin 中的 volley response liatner 在 recyclerview 中设置数据?
- django - 如何从 django 中的多个表中获取数据
- rust - Actix TCP 客户端实现的编译问题
- sql - 进行 1 对 1 多字段 SQL 联接,其中只有一些值匹配
- c# - ASP.NET,Entity Framework Code First 多对多自引用列表
- python - 如何使用 Python 从统计跟踪网站 (cod.tracker.gg) 抓取正确的元素
- java - android.widget.ProgressBar 不能转换为 android.widget.RelativeLayout