我如何在React JS中将Reducer的返回值设置为组件中的状态对象

时间:2020-04-21 16:38:24

标签: reactjs react-redux react-props

我有一个组成部分,如下所示。我在其componentDidMount()事件上调用api。我不明白为什么当组件渲染时我第一次没有获得它的道具价值。另外我不确定为什么组件渲染2次。我有下面的代码。

import React, { Component } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import AgmtTable from "./AgmtTable";
import * as AgmtAction from "../redux/actions/AgmtAction";

class AgmtContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  fetch Agmt details.
  componentDidMount() {
    this.props.dispatch(
      AgmtAction.getAgmtsForCustomer(
        this.props.match.params.custID,
        this.props.match.params.source,
        this.props.token
      )
    );
    console.log("componentDidMount", this.props.Agmts);
  }

  getHeaader = () => {
    var tableHeadings = [
      "Agmt ID",
      "Start Date",
      "End Date",
    ];
    return tableHeadings.map((key) => {
      return <th key={key}> {key.toUpperCase()}</th>;
    });
  };

  getRowsData = () => {
    console.log("in row data", this.props.Agmts);//here I cant see a data though its present in mapStateToProps() function. I am getting error as this.props.agreements.map is not a function.
     if (this.props.Agmts) {
       return this.props.Agmts.map((value) => {
         const {
           Agmt_ID,
           Agmt_START_DATE,
           End_DATE,

         } = value;
         return (
           <tr key={Agmt_ID} className="clickable-row active">
             <td> {Agmt_ID} </td>
             <td> {Agmt_START_DATE} </td>
             <td> {End_DATE} </td>
             </tr>
         );
       });
     }
  };

  render() {
    return (
      <React.Fragment>
        <div>
          <table
            id="display-table"
            className="table table-bordered table-hover table-responsive table-condensed table-striped table-sm"
          >
            <tbody>
              <tr>{this.getHeaader()}</tr>
              {this.getRowsData()}
            </tbody>
          </table>
        </div>
      </React.Fragment>
    );
  }
}

function mapStateToProps(state) {
  return {
    Agmts: state.AgmtsDetails.AgmtsData,//here I have a data
    token: state.login.userDetails.token,
  };
}

export default connect(mapStateToProps)(AgmtContainer);

我也该如何使用mapStateToProps值在状态对象中进行设置。当我在上面的代码上运行时,由于this.props.agmts.map不是函数

,因此出现错误

2 个答案:

答案 0 :(得分:1)

调度是异步的,因此您要么需要在结果中使用componentDidUpdate 来更新结果,要么要直接从化简器返回结果。

获得结果后,您可以对其进行处理并将其存储在本地状态中以在渲染中进行引用。请注意,除非您需要在其他位置的其他组件中引用结果,否则您无需将其存储在Redux中,就可以在组件中处理所有结果。

通过componentDidUpdate订阅商店:

componentDidMount() {
  this.props.dispatch(
    AgmtAction.getAgmtsForCustomer(
      this.props.match.params.custID,
      this.props.match.params.source,
      this.props.token
    )
  );
}

componentDidUpdate(prevProps) {
  if (JSON.stringify(prevProps.Agmts) !== JSON.stringify(this.props.Agmts)) {
    // this is the result of the dispatch
    console.log(this.props.Agmts);
  }
}

直接返回结果:

// in your AgmtAction.getAgmtsForCustomer action
export const getAgmtsForCustomer = () => (dispatch, getState) => {
  return axios
    .get(..........
    .then((res) => {
      dispatch(..........
        return res.data;
      })
    .catch((err) => {
      ...
    });
};

// in your `AgmtContainer` component
...
componentDidMount() {
  this.props.dispatch(
    AgmtAction.getAgmtsForCustomer(
      this.props.match.params.custID,
      this.props.match.params.source,
      this.props.token
    )
  ).then((res) => {
    // this is the result of the dispatch
    console.log(res);
  });
}

答案 1 :(得分:1)

在getRowsData函数中出现错误“映射不是函数”是由于在this.props.Agmts中获取的数据必须是对象类型。 (对象用大括号{}括起来)。

您只能将映射功能应用于数组,不能应用于对象。 (数组放在方括号[]中)