Redux不使用异步方法

时间:2019-07-19 21:19:00

标签: react-native redux

我的redux没有更新道具。

我的组件

...
import { connect } from 'react-redux';
import { getTenantByID, updateTenant } from '../actions';
...
constructor(props) {
    super(props);
    this.state = {
      tenantData: {}
    };
  }

  componentDidMount() {
    this.getTenant();
  }

  onChangeText = (text, input) => {
    const obj = { ...this.state.tenantData };

    obj[input] = text;

    this.setState({
      tenantData: obj
    });
  };

  onChangeNumberFormat = (text, input) => {
    const obj = { ...this.state.tenantData };

    let value = parseFloat(text);
    if (isNaN(value)) {
      value = 0;
    }
    value = parseFloat(value).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
    obj[input] = value;

    this.setState({
      tenantData: obj
    });
  };

  getTenant = async () => {
    const { navigation } = this.props;
    const tenantID = navigation.getParam('tenantID', '0');
    await this.props.getTenantByID(tenantID); // Wait for action to complete
    this.setState({
      tenantData: this.props.tenantData
    });
  };
...
const mapStateToProps = ({ tenants }) => {
  const { error, tenantData, saving } = tenants;

  return { error, tenantData, saving };
};

export default connect(mapStateToProps, {
  getTenantByID, updateTenant
})(TenantDetails);

在执行操作时,我导出方法:

export const getTenantByID = ({ tenantID }) => {
  return (dispatch) => {
    const getTenant = {
      FirstName: 'Jonh', LastName: 'Doe', Email: 'jonh@test.com', Phone: 'xxx-xxx-xxxx',
      Unit: '101', MiddleName: '', RentalAmount: '1000.50', MoveInDate: toDate('2019-01-01'),
      MoveOutDate: toDate('2019-12-01'), LeaseStartDate: toDate('2019-01-01'), LeaseEndDate: toDate('2019-12-01'),
    };
    dispatch({
      type: GET_TENANT_DATA,
      payload: getTenant
    });
  };
};

然后我使用化简器返回数据。

...
const INITIAL_STATE = {
  error: false,
  data: [],
  tenantData: {},
  saving: false,
};
...
case GET_TENANT_DATA:
      return { ...state, error: false, tenantData: action.payload };

如果我在化简版的GET_TENANT_DATA中执行console.log,我可以看到action.payload中包含数据。但是,如果我在我的render()方法中执行console.log(this.state.tenantData),它为空。为什么会发生?

谢谢

我将日志包含在componentDidMount中并进行渲染。按以下顺序显示

call render
this.props.tenantData is empty
Call componentDidMount
this.props.tenantData is empty
call render
this.props.tenantData has value
call render
this.props.tenantData has value

从不设置state.tenantData。为什么在componentDidMount()之后调用render()?

1 个答案:

答案 0 :(得分:1)

问题出在getTenant函数中。

  1. getTenant不应是异步函数,因为您没有返回承诺
    componentDidUpdate(prevProps){
      if (prevProps.tenantData.Email !== this.props.tenantData.Email) {// you need a unique value to check for changes in props
         this.setTenantData();
       }
    }

   setTenantData = () => this.setState({ tenantData: this.props.tenantData });

    getTenant = () => {
        const { navigation } = this.props;
        const tenantID = navigation.getParam('tenantID', '0');
        const tenantData = this.props.getTenantByID(tenantID); 
  };

这应该是您的操作。

export const getTenantByID = ({ tenantID }) => {
    const tenant = {
      FirstName: 'Jonh', LastName: 'Doe', Email: 'jonh@test.com', Phone: 'xxx-xxx-xxxx',
      Unit: '101', MiddleName: '', RentalAmount: '1000.50', MoveInDate: toDate('2019-01-01'),
      MoveOutDate: toDate('2019-12-01'), LeaseStartDate: toDate('2019-01-01'), LeaseEndDate: toDate('2019-12-01'),
    };

    return {
      type: GET_TENANT_DATA,
      payload: tenant
    };
};

因此,您可以在console.log的{​​{1}}下看到tenantData。

setState在componentDidUpdate下不起作用的原因是,在执行redux操作后,组件需要花费一些时间来更新