简体   繁体   English

由于 mapDispatchToProps 函数,如何避免重新渲染连接的 React PureComponent?

[英]How do I avoid re-rendering a connected React PureComponent due to mapDispatchToProps functions?

whenever mapDispatchToProps is called, it generates new functions to return.每当调用 mapDispatchToProps 时,它都会生成要返回的新函数。 For example:例如:

const mapDispatchToProps = function(dispatch, ownProps) {
  return {
    addToStack: (episodeId, stackId) => {
      return dispatch(StackAction.addEpisodeToStack(episodeId, stackId));
    },
  };
}

Every time the mapDispatchToProps is called, it will generate a new object, with a new arrow function.每次调用 mapDispatchToProps 时,它都会生成一个带有新箭头函数的新对象。

In my application I often have to avoid re-rendering my components.在我的应用程序中,我经常不得不避免重新渲染我的组件。 Using a PureComponent is often the way to go.使用 PureComponent 通常是可行的方法。 However, since the functions are always different, PureComponent won't help and I'd have to create a shouldComponentUpdate strategy.然而,由于功能总是不同的,PureComponent 无济于事,我必须创建一个 shouldComponentUpdate 策略。 There, I'd have to "blacklist" all of the mapDispatchToProps functions and ignore all of them.在那里,我必须将所有 mapDispatchToProps 函数“列入黑名单”并忽略所有这些函数。 I'd have to add every new function to the list so it'd avoid re-rendering.我必须将每个新函数添加到列表中,以免重新渲染。

here is an example of the blacklist shouldComponentUpdate boilerplate:这是黑名单 shouldComponentUpdate 样板的示例:

const blacklist = [
  'addToStack',
]

shouldComponentUpdate(nextProps, nextState) {
  for (let i in nextProps) {
    if (blacklist.includes(i)) continue;
    if (nextProps[i] !== this.props[i]) {
      return true;
    }
  }
  for (let i in nextState) {
    if (nextState[i] !== this.state[i]) {
      return true;
    }
  }
  return false;
}

I've come up with a new solution我想出了一个新的解决方案

const dispatch;
const mapDispatchToPropsFunctions = {
  addToStack: (episodeId, stackId) => {
    return dispatch(StackAction.addEpisodeToStack(episodeId, stackId));
  },
};

const mapDispatchToProps = function(dispatchArg, ownProps) {
  dispatch = dispatchArg
  return mapDispatchToPropsFunctions;
}

this way the functions are constant and won't trigger a re-rendering of a PureComponent and I don't have to maintain a shouldComponentUpdate function.这样,函数是恒定的,不会触发 PureComponent 的重新渲染,而且我不必维护 shouldComponentUpdate 函数。

however this seems wrong to me.然而这对我来说似乎是错误的。 Is there a "default" way of dealing with this problem?有没有处理这个问题的“默认”方式?

I generally advise to not try to recreate functions that capture props values like that, but instead have a handler method on your class that passes prop values to the action creator.我通常建议不要尝试重新创建像这样捕获 props 值的函数,而是在您的类上使用一个处理程序方法,将 prop 值传递给动作创建者。 I also advise that people not write mapDispatch functions directly, but use the "object shorthand" for connect() .我还建议人们不要直接编写mapDispatch函数,而是使用connect()的“对象简写”。

Example:示例:

const actions = {addToStack : StackAction.addEpisodeToStack};

class MyComponent extends React.Component {
    addToStack = () => {
        this.props.addToStack(this.props.episodeId, this.props.stackId);
    }
}

In your specific snippet, it looks like you're not even referencing any props values in mapDispatch anyway, so there was no need to declare the ownProps parameter.在您的特定代码段中,您似乎甚至没有在mapDispatch引用任何道具值,因此无需声明ownProps参数。 ( connect will only call a mapDispatch function multiple times if the ownProps parameter is requested. Otherwise, it only calls mapDispatch once, when the component is created.) (如果请求了ownProps参数, connect只会多次调用mapDispatch函数。否则,它只会在创建组件时调用一次mapDispatch 。)

Turns out that the actual solution is to not use mapDispatchToProps at all.事实证明,实际的解决方案是根本不使用mapDispatchToProps In the react-redux docs there is a reference to a shorthand method:react-redux 文档中有对速记方法的引用:

If an object is passed, each function inside it is assumed to be a Redux action creator.如果传递了一个对象,则假定其中的每个函数都是 Redux 动作创建者。 An object with the same function names, but with every action creator wrapped into a dispatch call so they may be invoked directly, will be merged into the component's props.具有相同函数名称但每个动作创建者都包含在调度调用中以便可以直接调用它们的对象将合并到组件的 props 中。

So the solution is to, instead of providing a function that binds dispatch to your action creators, just provide to connect an object containing your action creators as second argument.所以解决方案是,不是提供一个将调度绑定到你的动作创建者的函数,而是提供连接一个包含你的动作创建者的对象作为第二个参数。 Connect will only bind them once and use the same functions all the time, avoiding unnecessary re-renders. Connect 只会绑定它们一次并一直使用相同的功能,避免不必要的重新渲染。

This should be in fact the preferred way of supplying action creators to connect.这实际上应该是提供动作创建者进行连接的首选方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何避免由于道具更改而重新渲染组件以解决性能问题 - How can I avoid re-rendering of component due to props change, to fix performance problems 如何正确更新 React Context state 并避免重新渲染? - How to properly update React Context state and avoid re-rendering? 如何避免在React Component中使用事件侦听器进行无限重新渲染? - How to avoid infinite re-rendering with event listener in React Component? 如何避免React Component的不必要的重新渲染 - How to avoid unnecessary re-rendering of React Component React - 避免重新渲染对象属性 - React - avoid re-rendering an object property 避免在 React 中重新渲染整个列表 - Avoid re-rendering whole list in React 更改状态后React不重新呈现,我如何设置子组件的状态? - React not re-rendering after a change in state, how do I setState of child components? 如何防止React Router 4在URL切换时重新呈现? - How do I prevent React Router 4 from re-rendering on URL switch? react-native-maps:如何在不重新渲染整个地图的情况下添加标记? - react-native-maps: How do I add markers without re-rendering the entire map? 如何防止在React中使用钩子重新渲染页面? - How can I prevent re-rendering of the page with hooks in React?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM