【问题标题】:react + redux + normalizer: How to send conditional denormalized data?react + redux + normalizer:如何发送条件非规范化数据?
【发布时间】:2020-07-30 07:02:50
【问题描述】:

例如简单的country-region选择任务(两个组合框) 我从第一个组合框中选择 'country' 并将其 ID 保持在组件状态。接下来,我必须为选定的 country ID 加载 'regions' - 在某些调度方法中执行此操作。它的一切工作完美。好的,redux 存储包含所有必需的数据...我只需要将加载的 regions 发送到组件... 但! 在 mapStateToProps 我没有组件状态(选择 'country' ID),所以我需要传递所有 'regions' (适用于所有国家) 到组件道具...好吧...

我正在使用 normalizr 并且 Redux 存储中的所有数据都已标准化。并且非规范化需要所有实体(因为引用),所以我必须将所有 redux 存储传递给组件道具......似乎不太好:非规范化不是组件职责,mapStateToProps 是最合适的地方,但是非规范化所有 regionsmapStateToProps 中没有国家 ID)可能会消耗太多时间...

此类任务的最佳实践是什么?

【问题讨论】:

  • 你为加载区域发送了什么?您没有发送国家/地区 ID 吗?

标签: reactjs redux normalizr


【解决方案1】:

好吧,不确定是否有解决方案,但使用 HOC(自定义 withDynamicProps 方法)似乎可以工作:

import React from "react";

function withDynamicProps(Component, initalProps = {}) {
  return class extends React.Component {
    constructor(props) {
      super(props);

      this.state = initalProps;
      this.setDynamicProps = this.setDynamicProps.bind(this);
    }

    setDynamicProps(dynamicProp) {
      this.setState(dynamicProp);
    }

    render() {
      return (
        <Component
          {...this.props}
          {...this.state}
          setDynamicProps={this.setDynamicProps}
        />
      );
    }
  };
}

export { withDynamicProps };

在我的容器-组件中:

class ContainerComponent extends Component {
  ....

  componentDidMount() {
    const { countryId } = this.props;

    loadCountries();

    if (countryId) {
      loadRegions(countryId);
    }
  }

  componentDidUpdate(prevProps, prevState) {
    const { prevState} = this.props;

    if (countryId && prevState.countryId !== countryId) {
      loadRegions(countryId);
    }
  }

  onCountryChangeHandler(countryId) {
    this.props.setDynamicProps({ countryId });
  }

  render() {
    const { countriesList, regionsList, countryId } = this.props;

    return (
      <PresentationComponent {...this.props}/>
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  const {
    countryId
  } = ownProps;

  const {
    entities: { countries, regions },
    associativitiesRefs: { regionsByCountry }
  } = state;

  const countriesList = Object.keys(countries).map(x =>
    denormalize(countries[x], Schemas.COUNTRY, state.entities)
  );

  const regionsIdByCountry = regionsByCountry[countryId] || {
    ids: []
  };

  const regionsList = regionsIdByCountry.ids.map(x =>
    denormalize(regions[x], Schemas.REGION, state.entities)
  );

  return {
    countriesList,
    regionsList
  };
};

export default withDynamicProps(
  withRouter(
    connect(
      mapStateToProps,
      {
        loadCountries,
        loadRegions
      }
    )(ContainerComponent)
  )
);

【讨论】:

    【解决方案2】:

    normalized-reducer 库提供了一种无需编写任何 reducer 逻辑即可管理规范化状态的方法,并包含一个 normalizr adapter,可以将您的 normalizr 输出转换为与 reducer 兼容的初始状态。

    【讨论】:

    • 它有什么帮助?主要问题:国家和地区之间的模式没有关系......我想要一些 control stateconnect 参数之一:mapStateToProps/mergeProps...另一种方式:使特定的调度道具功能,这将返回良好的数据,但有两次重新渲染......我是react / redux的新手,所以我想知道此类任务的最佳实践(在react-redux中过滤复杂的标准化数据)
    • 能否提供一个标准化数据的小例子
    猜你喜欢
    • 2016-12-27
    • 1970-01-01
    • 2017-05-25
    • 2017-01-14
    • 2017-04-25
    • 2014-12-23
    • 2020-04-06
    • 2010-10-06
    • 1970-01-01
    相关资源
    最近更新 更多