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

时间:2016-08-09 19:00:12

标签: reactjs redux flux react-redux

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

示例App

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毫秒更新一次,而内容组件永远不会更新,因为它的reducer将始终返回相同的状态。

然而我发现每次触发一个动作时两个组件都会执行reRender非常奇怪。

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

2 个答案:

答案 0 :(得分:18)

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

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

在React中提高UI性能的核心方法是使用shouldComponentUpdate生命周期方法检查传入的props,如果组件不需要重新渲染,则返回false。这将导致React跳过重新呈现该组件的所有后代。 shouldComponentUpdate中的比较通常使用浅参考相等来完成,这是相同的对象引用意味着不更新&#34;事情变得有用。

使用Redux和connect时,您几乎总会发现自己在UI中的许多不同组件上使用connect。这提供了许多好处。组件可以单独提取他们需要的存储状态的各个部分,而不必将它们全部从根组件中移除。此外,connect为您实现默认shouldComponentUpdate对您从mapStateToProps函数返回的值进行类似检查。因此,从某种意义上说,在多个组件上使用connect往往会给你一个免费的胜利&#34;在表现方面。

进一步阅读该主题:

答案 1 :(得分:8)

是的,这是设计的。行动已发送。减速机运行。商店订阅者会收到“商店已更改”的通知。连接的组件是商店订户。

通常情况下,在实际测量可归因于此的性能问题之前,您不必担心它 - 不要过早地优化。

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

  • 为您的组件添加shouldComponentUpdate方法,以便他们可以看到他们收到的道具没有不同,也不需要渲染(有很多Pure Render mixins和高阶组件可用于制作此组件易)
  • 不是连接顶级应用,而是直接连接Navbar和Content组件。应用程序将永远不会重新呈现,但如果商店发生变化,孩子们将会这样做。而react-redux会自动使用shouldComponentUpdate来重新渲染实际拥有新道具的连接组件。