反应Redux派遣

mo_size

调用分派以获取React组件上的初始数据的最佳方法是什么。我的理解是ComponentWillMount在渲染之前被调用。因此,从理论上讲,如果我在ComponentWillMount上调用dispatch,那么在我点击render然后再到ComponentDidMount时,我应该将数据保存在组件的props中,对吗?我没看到

我看到渲染两次被调用,并且在初始化组件时第一次被调用,我无法访问props中的数据。看起来好像直到第二个渲染才真正调用dispatch。我基本上是希望在最初设置组件时能找到一些最好的方法来调用调度。我实质上是在尝试执行以下操作,在该操作中,我使用容器组件从调度中获取数据,然后将其作为道具传递给子组件。但是我也想在ContainerComponent中初始化一些状态变量,然后将它们作为道具传递给ChildComponent。问题是我要初始化的状态变量取决于分派返回的数据,理想情况下,我将在ComponentWillMount或ComponentDidMount中进行初始化。

import React from 'react';
import axios from 'axios';

import { connect } from 'react-redux';
import ChildComponent from './ChildComponent.js';

import { getTransactionsAll } from '../actions/actions.js';

class ContainerComponent extends React.Component {
  constructor() {
    super();
    this.state = {
      acctList:[],
      acctChecked:[],
      categoryList:[]
    }
}
  componentWillMount() {

    console.log("componentWillMount entered");

    this.props.get_data();
    console.log(this.props.searchProps.transactions_all);//this is undefined meaning the dispatch has not assigned the data yet...??

  }

  componentDidMount() {
    console.log("componentDidMount entered");
    console.log(this.props.searchProps.transactions_all);//this is undefined meaning the dispatch has not assigned the data yet...??
}

  render() {

    console.log("TransactionManagerContainer render entered");
    console.log(this.props.searchProps.transactions_all);//this is undefined the first time around meaning the dispatch has not assigned the data yet...??, but is defined on the second call to render after the dispatch has actually occurred...

return <ChildComponent
             data={this.props.searchProps.data}/>;
}

const mapStateToProps = (state) => ({
  searchProps: state.searchProps
});

export default connect(mapStateToProps, {getTransactionsAll})(TransactionManagerContainer);

这是分配状态的我的减速器:

import { combineReducers } from 'redux'

import {GET_TRANSACTIONS } from '../actions/actions.js'
import {GET_TRANSACTIONS_ALL } from '../actions/actions.js'

const INITIAL_STATE = { defaultYear: 2016, transactions: []};

function get_transactions(state = INITIAL_STATE, action) {
  // console.log("this is in the reducer: get_transactions");
  // console.log(action);
  switch(action.type) {
    case GET_TRANSACTIONS:
      // return { ...state, transactions: action.payload };
      return Object.assign({}, state, {
        transactions: action.payload,
        selectedYear: action.selectedYear
      })
    default:
      return state;
  }
}

function get_transactions_all(state = INITIAL_STATE, action) {
  console.log("this is the value of action in the reducer: get_transactions_all");
  console.log(action);
  switch(action.type) {
    case GET_TRANSACTIONS_ALL:
      // return { ...state, transactions: action.payload };
      return Object.assign({}, state, {
        transactions_all: action.payload
      })
      console.log("this is the value of state in the reducer after being set");
      console.log(state);
    default:
      return state;
  }
}

const rootReducer = combineReducers({
  //stateProps: get_transactions,
  searchProps: get_transactions_all
})

export default rootReducer

这是我的动作:

import axios from 'axios';

export const GET_TRANSACTIONS = 'GET_TRANSACTIONS';

export function getTransactions(year) {
 return function(dispatch) {
  axios.get(`http://localhost:3001/api/transfilter?year=${year}&grouping=2`)
   .then(response => {
     dispatch({
       type: GET_TRANSACTIONS,
       payload: response.data,
       selectedYear: year
     });
   })
   .catch((error) => {
     console.log(error);
   })
 }
}

export const GET_TRANSACTIONS_ALL = 'GET_TRANSACTIONS_ALL';

export function getTransactionsAll(year) {
 return function(dispatch) {
  axios.get(`http://localhost:3001/api/trans?limit=20`)
   .then(response => {

     dispatch({
       type: GET_TRANSACTIONS_ALL,
       payload: response.data
     });
   })
   .catch((error) => {
     console.log(error);
   })
 }
}
卡洛扬·科塞夫(Kaloyan Kosev)

我相信您的主要问题是:

调用分派以获取React组件上的初始数据的最佳方法是什么?

获取初始数据请求(或通常的任何AJAX请求)应该在componentDidMount生命周期事件中进行。

有几个原因,这里有两个重要的原因:

  1. Fiber是React协调算法的下一个实现,将能够根据需要启动和停止渲染,以提高性能。这方面的权衡之一是componentWillMount(另一个生命周期事件,它可能对AJAX请求有意义)将是“不确定的”。这意味着React可能会在需要时随时开始调用componentWillMount。对于AJAX请求,这显然是一个不好的公式。

  2. 您不能保证在组件安装之前AJAX请求不会得到解决。如果确实如此,那意味着您将尝试在未安装的组件上设置setState,这不仅不起作用,而且React也会为您大喊大叫。在componentDidMount中执行AJAX可以确保存在要更新的组件。

积分:我了解到,从这里,也有讨论这里

然后,您提出了很多较小的问题,这对我来说很难回答,但我将尽力介绍大多数问题:

  • 阅读以上内容后,您现在应该了解为什么数据undefined位于componentWillMount和中componentDidMount这仅仅是因为数据还没有到达。
  • undefined在组件的第一次渲染期间,数据是正常的。初始渲染发生在数据到达之前;
  • 在第二次渲染期间定义数据是正常的。dispatch触发器的异步数据提取。数据到来后,立即reducer命中a并重新渲染组件(这是第二次重新渲染)。
  • 如果主组件中的子组件需要数据,请检查父render方法是否存在数据(仅当存在数据时)有条件地通过内部组件。像这样:

    class ContainerComponent extends React.Component {
      // ... omitted for brevity
    
      render() {
        return (
          { this.props.searchProps.data ?
              <ChildComponent
                data={this.props.searchProps.data} />
              : <p>Loading</p>
          }
        );
      }
    }
    

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章