【问题标题】:How to get initialValues for a reduxFrom from state?如何从状态中获取 reduxFrom 的初始值?
【发布时间】:2019-02-11 20:45:02
【问题描述】:

我正在使用我的表单和 react redux。我有相同的表格来编辑和创建一个新表格。

我希望,在打开我的表单时,如果进行编辑,我会从我的 api 中输入表单的初始值。

我已经尝试过官方文档,但它不起作用。

这是我的表格:

class Form extends Component {

  componentDidMount () {
    const tripId = this.props.match.params.uid;
    if(tripId){
      this.fetchData(tripId);
    }
  }

  fetchData = async (tripId) => {
    axios.defaults.headers.common['Authorization'] = 'token';
    axios.defaults.headers.common['Accept'] = 'application/vnd.trips.v1+json';
    await axios.get(`myurl`) 
    .then(res => {
      const trip = res.data;
      this.setState({ 
        trip: trip,
        isLoading: false,
        initialValues: trip
      });
    })
    console.log('Terminou de carregar')
  }

(....)
Form = reduxForm({ form: 'trip', enableReinitialize : true })(Form)
const mapStateToProps = state => {
  const { intl, vehicleTypes, users, dialogs, trip } = state

  return {
    intl,
    vehicleTypes,
    users,
    dialogs,
    initialValues: trip
  }
}

export default connect(
  mapStateToProps, { setDialogIsOpen }
)(injectIntl(withRouter(withTheme()(Form))))

但我的 initialValues 从未填充,总是空白。我调试了代码,我看到我的 API 正在加载并设置我的 fetchData 方法的状态。那么,我在这里做错了什么?

【问题讨论】:

    标签: reactjs react-redux redux-form


    【解决方案1】:

    首先,您试图通过this.setState 传递initialValues,但这是行不通的,reduxForm 期望initialValuesprops 的形式传递。

    要提一点,application statecomponent local state 是有区别的,第一个 -application state- 显然是由 redux 管理的,另一个 -local component state- 是由 react 管理的,你可以调用this.setState修改

    所以要解决这个问题,您应该在从您的 api 接收数据时分派一个操作,并在 mapStateToProps 中更新您的道具

    您的代码应如下所示:

    class Form extends Component {
    
      componentDidMount () {
        const tripId = this.props.match.params.uid;
        if(tripId){
          this.fetchData(tripId);
        }
      }
    
      fetchData = async (tripId) => {
        await axios.get(`https://toptal-backend-fmaymone.c9users.io/trips/${tripId}`) 
        .then(res => {
          const trip = res.data;
          this.props.fillTheForm(trip);
        })
        console.log('Terminou de carregar')
      }
    
    (....)
    Form = reduxForm({ form: 'trip', enableReinitialize : true })(Form)
    const mapStateToProps = state => {
      const { intl, vehicleTypes, users, dialogs, trip } = state
    
      return {
        intl,
        vehicleTypes,
        users,
        dialogs,
        initialValues: trip
      }
    }
    
    const fillTheForm = (dispatch) => (trip) => {
      // here you dispatch the action and update your application state
      // in your reducer when this action is dispatched,
      // then mapStateToProps should be called and the data you just
      // passed in your reducer should be in (state)
      dispatch()
    }
    
    export default connect(
      mapStateToProps, { setDialogIsOpen, fillTheForm }
    )(injectIntl(withRouter(withTheme()(Form))))
    

    【讨论】:

    • 感谢@d7my 的澄清。但我仍然不明白如何在 fillTheForm 方法中设置状态。因为我不能添加 this.setState{initialValues: dispatch} (因为当然“this”在箭头函数内是不可访问的
    【解决方案2】:

    正如@d7my 所说,您的错误是您试图通过setState 更改prop,它们在反应世界中是不同的东西。解决问题的最快方法是替换它:

    this.setState({
       trip: trip,
       isLoading: false,
       initialValues: trip
    });
    

    为:

    this.props.initialize(trip)
    

    prop initialize 被 redux-form 导出到你的组件,以更新表单初始状态。我创建了一个codesandbox,您可以在其中检查它是否正常工作。

    也就是说,我认为您应该更改组件的结构,而不是在组件中加载数据(componentDidMount),您应该在 redux 操作中执行此操作,然后更新您的状态。这样做,您可以轻松地在 mapStateToProps 函数上从您的 redux 状态获取表单数据并设置 initialValues 道具而不是使用 initialize 道具,这样会更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      相关资源
      最近更新 更多