【问题标题】:how can I set the reducer's return value to state object in component in react js如何将reducer的返回值设置为react js组件中的状态对象
【发布时间】:2020-04-21 16:38:24
【问题描述】:

我有一个组件如下。我在其 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 不是函数

【问题讨论】:

    标签: reactjs react-redux react-props


    【解决方案1】:

    dispatch 是异步的,因此您要么需要使用componentDidUpdate 观察要在 Redux 存储中更新的结果,要么直接从 reducer 返回结果。

    当您获得结果时,您可以对其进行操作并将其存储在本地状态以在您的渲染中引用。请注意,除非您需要在某个地方引用另一个组件中的结果,否则您不需要将其存储在 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);
      });
    }
    

    【讨论】:

    • 您不仅解决了我的问题,还提供了有关 redux 使用的额外信息,这有助于我减少不必要的商店更新。我希望我能给你的答案投票 100 次。非常感谢您的帮助。
    【解决方案2】:

    在 getRowsData 函数中,您收到错误“map is not a function”是由于您在 this.props.Agmts 中获取的数据必须是对象类型。 (对象括在大括号 {} 中)。

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

    【讨论】:

    • 这也是问题之一。但是在使它成为数组之后,我没有得到值。按照以下代码进行更改后,它运行顺利。感谢您的帮助。
    猜你喜欢
    • 2016-12-18
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多