限制 Redux 仅更新受更改影响的组件

Limit Redux to update only components affected by the change

试图理解 React-Redux,我发现当状态的任何部分发生变化时,我的所有组件都会获得新的道具是不寻常的。这是设计使然还是我做错了什么?

示例应用程序

class App extends React.Component {

  render(){return (
          <div> 
            <Navbar data={this.props.navbar} />
            <Content data={this.props.content} />
          </div>);
  }

}
select (state) => ({ navbar:state.navbar, content:state.content});
export default connect(select)(App);

组件

export const NavbarForm = props => {
  console.log('RENDERING with props--->',props);
  return (<h1>NAV {props.data.val}</h1>);
};
export const ContentForm = props => {
  console.log('RENDERING CONTENT with props--->',props);
  return (<h1>CONTENT {props.data.val}</h1>);
};

////////INDEX.js//////

const placeholderReducer = (state={val:0},action)=>{
//will update val to current time if action start with test/;
if(action.type.indexOf('TEST/') === 0)return {val:Date.now();}

return state;
}

export const rootReducer = combineReducers({
  navbar:placeholderReducer,
  content: (state,action)=>(state || {}), //**this will never do a thing.. so content should never updates right !!**
});

const store = createStore(rootReducer, {}, applyMiddleware(thunk));

render( <Provider store={store}> <App /></Provider>, document.getElementById('app')
);
setInterval(()=>{  store.dispatch(()=>{type:'TEST/BOOM'})  },3000);

好的,在这个应用程序中,我期望 Navbar 组件每 3000 毫秒更新一次,而内容组件永远不会更新,因为它的缩减器将始终 return 相同的状态。

但我发现这两个组件在每次触发操作时都会重新渲染真的很奇怪。

这是设计使然吗?如果我的应用有 100 多个组件,我应该担心性能吗?

是的,这是设计使然。动作被分派。减速机 运行。商店订阅者会收到通知 "the store has changed"。连接的组件是商店订阅者。

通常情况下,您不必担心它,直到您可以实际衡量可归因于此的性能问题 - 不要过早优化。

如果您发现它一个问题,那么您可以执行以下操作之一:

  • 向您的组件添加一个 shouldComponentUpdate 方法,这样他们就可以看到他们收到的道具没有不同并且不需要渲染(有很多 Pure Render mixins 和高阶组件可用于制作这很容易)
  • 不连接 top-level 应用程序,而是直接连接导航栏和内容组件。该应用程序永远不会重新呈现,但 children 会在商店发生变化时重新呈现。 react-redux 自动使用 shouldComponentUpdate 仅 re-render 实际具有新道具的连接组件。

这完全是设计使然。 React 假定您的整个应用程序默认会从上到下重新呈现,或者如果某个组件执行 setState 或类似操作,至少会重新呈现给定的子树。

因为您只连接了应用程序中最顶层的组件,所以从那里往下的所有内容都是 React 的标准行为。父组件重新渲染,导致其所有子组件重新渲染,导致所有 它们的 子组件重新渲染,依此类推。

在 React 中提高 UI 性能的核心方法是使用 shouldComponentUpdate 生命周期方法检查传入的 props 和 return false 如果组件不需要重新渲染。这将导致 React 跳过重新渲染该组件 它的所有后代。 shouldComponentUpdate 中的比较通常使用浅引用相等来完成,这就是 "same object references means don't update" 有用的地方。

当使用 Redux 和 connect 时,您几乎总是会发现自己在 UI 的许多不同组件上使用 connect。这提供了许多好处。组件可以单独提取它们需要的存储状态的片段,而不是必须从根组件将它们全部传递下来。此外,connect 为您实现默认值 shouldComponentUpdate 对您 return 来自 mapStateToProps 的值进行类似检查功能。因此,从某种意义上说,在多个组件上使用 connect 往往会给您带来 "free win" 的性能。

关于该主题的进一步阅读: