react + redux + normalizer:如何发送条件非规范化数据?

Posted

技术标签:

【中文标题】react + redux + normalizer:如何发送条件非规范化数据?【英文标题】:react + redux + normalizer: How to send conditional denormalized data? 【发布时间】: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 吗? 【参考方案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中过滤复杂的标准化数据) 能否提供一个标准化数据的小例子

以上是关于react + redux + normalizer:如何发送条件非规范化数据?的主要内容,如果未能解决你的问题,请参考以下文章

[Redux] Normalizing the State Shape

React+Redux学习笔记:React+Redux简易开发步骤

Redux 进阶之 react-redux 和 redux-thunk 的应用

React之React-redux数据流转流程

react-redux

redux和react-redux