Как я могу установить возвращаемое значение редуктора для состояния объекта в компоненте в реакции js - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть один компонент, как показано ниже. Я звоню на API по событию componentDidMount (). Я не понимаю, почему я не получаю его значение в первый раз, когда компонент рендерится. Также я не уверен, почему компонент рендерит 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 ]

1 голос
/ 22 апреля 2020

В функции getRowsData, где вы получаете сообщение об ошибке «карта не является функцией», это связано с данными, которые вы получаете в this.props.Agmts должен быть типом объекта. (Объект заключен в фигурные скобки {}).

Вы можете применять функцию карты только к массиву, а не к объекту. (Массив заключен в квадратные скобки [])

1 голос
/ 21 апреля 2020

Отправка асинхронная, поэтому вам нужно либо следить за обновлением результата в вашем хранилище Redux, либо 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);
  });
}
...