wrapMapToProps.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import verifyPlainObject from '../utils/verifyPlainObject';
  2. export function wrapMapToPropsConstant( // * Note:
  3. // It seems that the dispatch argument
  4. // could be a dispatch function in some cases (ex: whenMapDispatchToPropsIsMissing)
  5. // and a state object in some others (ex: whenMapStateToPropsIsMissing)
  6. // eslint-disable-next-line no-unused-vars
  7. getConstant) {
  8. return function initConstantSelector(dispatch) {
  9. const constant = getConstant(dispatch);
  10. function constantSelector() {
  11. return constant;
  12. }
  13. constantSelector.dependsOnOwnProps = false;
  14. return constantSelector;
  15. };
  16. } // dependsOnOwnProps is used by createMapToPropsProxy to determine whether to pass props as args
  17. // to the mapToProps function being wrapped. It is also used by makePurePropsSelector to determine
  18. // whether mapToProps needs to be invoked when props have changed.
  19. //
  20. // A length of one signals that mapToProps does not depend on props from the parent component.
  21. // A length of zero is assumed to mean mapToProps is getting args via arguments or ...args and
  22. // therefore not reporting its length accurately..
  23. // TODO Can this get pulled out so that we can subscribe directly to the store if we don't need ownProps?
  24. export function getDependsOnOwnProps(mapToProps) {
  25. return mapToProps.dependsOnOwnProps ? Boolean(mapToProps.dependsOnOwnProps) : mapToProps.length !== 1;
  26. } // Used by whenMapStateToPropsIsFunction and whenMapDispatchToPropsIsFunction,
  27. // this function wraps mapToProps in a proxy function which does several things:
  28. //
  29. // * Detects whether the mapToProps function being called depends on props, which
  30. // is used by selectorFactory to decide if it should reinvoke on props changes.
  31. //
  32. // * On first call, handles mapToProps if returns another function, and treats that
  33. // new function as the true mapToProps for subsequent calls.
  34. //
  35. // * On first call, verifies the first result is a plain object, in order to warn
  36. // the developer that their mapToProps function is not returning a valid result.
  37. //
  38. export function wrapMapToPropsFunc(mapToProps, methodName) {
  39. return function initProxySelector(dispatch, {
  40. displayName
  41. }) {
  42. const proxy = function mapToPropsProxy(stateOrDispatch, ownProps) {
  43. return proxy.dependsOnOwnProps ? proxy.mapToProps(stateOrDispatch, ownProps) : proxy.mapToProps(stateOrDispatch, undefined);
  44. }; // allow detectFactoryAndVerify to get ownProps
  45. proxy.dependsOnOwnProps = true;
  46. proxy.mapToProps = function detectFactoryAndVerify(stateOrDispatch, ownProps) {
  47. proxy.mapToProps = mapToProps;
  48. proxy.dependsOnOwnProps = getDependsOnOwnProps(mapToProps);
  49. let props = proxy(stateOrDispatch, ownProps);
  50. if (typeof props === 'function') {
  51. proxy.mapToProps = props;
  52. proxy.dependsOnOwnProps = getDependsOnOwnProps(props);
  53. props = proxy(stateOrDispatch, ownProps);
  54. }
  55. if (process.env.NODE_ENV !== 'production') verifyPlainObject(props, displayName, methodName);
  56. return props;
  57. };
  58. return proxy;
  59. };
  60. }