如何使用React和Redux在表中提供动态计算的数据

时间:2019-04-14 09:06:19

标签: javascript arrays reactjs react-redux

如何使用redux并使用refux中的函数做出反应以渲染动态计算的数据? 详细信息:我试图用两列(名称,共享)呈现表。 名称来自entity.name,共享是使用entity.id和远程服务计算的数据。目前,我已经使用表的名称动态渲染了每个实体具有行的表,但是我无法按entity.id传递计算的数据。

我尝试使用redux操作来做到这一点,但是现在我了解到redux操作不会返回任何值,而是会修改其存储中的状态。我在下面使用{calculateShare(entity.id)}提供的代码给我错误,它返回数组{type,payload}。 另一个选择可能是在redux存储中构建键/值数组,并通过使用entity.id作为键来获取数组值,从而在rea​​ct表中使用它,但是我不确定如何在reducer中正确地执行该操作并进行响应代码。

Reducer看起来像这样:

export const getCalculatedShareById: IPayloadResult<String> = id => {
  const requestUrl = `${apiUrl}/${id}/calculated-share`;
  return {
    type: ACTION_TYPES.FETCH_ENTITY_CALCULATED_SHARE,
    payload: axios.get<String>(requestUrl)
  };
};

我使用reducer的主页响应示例:

export class Home extends React.Component {
  componentDidMount() {
    this.props.getEntities();
  }

  render() {
    const { entitiesList, getCalculatedShareById } = this.props;
    return (
      <Row>
        <Col>
          <Table>
            <thead>
              <tr>
                <th>Name</th>
                <th>Share</th>
              </tr>
            </thead>
            <tbody>
              {entitiesList.map((entity, i) => (
                <tr key={`entity-${i}`}>
                  <td>{entity.name}</td>
                  <td>{getCalculatedShareById(entity.id)}</td>
                </tr>
              ))}
            </tbody>
          </Table>
        </Col>
      </Row>
    );
  }
}

const mapStateToProps = storeState => ({
  entitiesList: storeState.myReducer.entities
});

const mapDispatchToProps = { getEntities, getCalculatedShareById};

type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = typeof mapDispatchToProps;

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Home);

请帮助我了解解决此类问题的最佳方法,并在可能的情况下提供一些示例。

2 个答案:

答案 0 :(得分:0)

流程应该是这样

  1. 执行调度。
  2. 通过reducer中的调度更新状态entity
  3. mapStateToProps entity中,状态已导入到 组件,我们执行操作后此变量将更新 (正是在减速器中)。
  4. 触发分派后,我们可以访问修改后的变量 通过this.props.entityList

上述执行中缺少的是化简器,因此我们需要实现一个以state和动作-> {type: x, payload: y}为参数并修改state的entity属性的化简器并返回修改后的state

答案 1 :(得分:0)

最后,我创建了一个Web服务方法,该方法计算每个实体的份额数量,将这些数据映射到地图上,然后使用axios和redux进行响应。不确定这是否是解决我的问题的最佳方法,但它确实有效。

我的工作代码示例=> 减速器:

export const ACTION_TYPES = {
  FETCH_ENTITY_SHARE_AMOUNT: 'entity/FETCH_ENTITY_SHARE_AMOUNT'
};

const initialState = {
  loading: false,
  errorMessage: null,
  entitiesShareAmountMap: Map,
  updating: false,
  updateSuccess: false
};

export type EntityState = Readonly<typeof initialState>;

// Reducer

export default (state: EntityState = initialState, action): EntityState => {
  switch (action.type) {
    case REQUEST(ACTION_TYPES.FETCH_ENTITY_SHARE_AMOUNT):
      return {
        ...state,
        errorMessage: null,
        updateSuccess: false,
        loading: true
      };
    case FAILURE(ACTION_TYPES.FETCH_ENTITY_SHARE_AMOUNT):
      return {
        ...state,
        loading: false,
        updating: false,
        updateSuccess: false,
        errorMessage: action.payload
      };
    case SUCCESS(ACTION_TYPES.FETCH_ENTITY_SHARE_AMOUNT):
      return {
        ...state,
        loading: false,
        entitiesShareAmountMap: action.payload.data
      };
    default:
      return state;
  }
};

const apiUrl = 'api/entities';

// Actions

export const getEntitiesShareAmountMap: IPayloadResult<any> = () => {
  const requestUrl = `${apiUrl}/entities-share-amount`;
  return {
    type: ACTION_TYPES.FETCH_ENTITY_SHARE_AMOUNT,
    payload: axios.get<Map<String, String>>(requestUrl)
  };
};

反应成分:

export class Home extends React.Component {
  componentDidMount() {
    this.props.getEntities();
    this.props.getEntitiesShareAmountMap();
  }

  render() {
    const { entitiesList, entitiesShareAmountMap } = this.props;
    return (
      <Row>
        <Col>
          <Table>
            <thead>
              <tr>
                <th>Name</th>
                <th>Share</th>
              </tr>
            </thead>
            <tbody>
              {entitiesList.map((entity, i) => (
                <tr key={`entity-${i}`}>
                  <td>{entity.name}</td>
                  <td>{entitiesShareAmountMap[lottery.id]}</td>
                </tr>
              ))}
            </tbody>
          </Table>
        </Col>
      </Row>
    );
  }
}

const mapStateToProps = storeState => ({
  entitiesList: storeState.myReducer.entities,
  entitiesShareAmountMap: storeState.myReducer.entitiesShareAmountMap
});

const mapDispatchToProps = { getEntities, getEntitiesShareAmountMap };

type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = typeof mapDispatchToProps;

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Home);