如何从状态中获取 reduxFrom 的初始值?
How to get initialValues for a reduxFrom from state?
我正在使用带有 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 方法的状态。那么,我在这里做错了什么?
首先,您试图通过 this.setState
传递 initialValues
这是行不通的,reduxForm 期望 initialValues
作为 props
传递。
有一点要提一下,application state
和component 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 所说,您的错误是您试图通过 setState
更改 prop
,它们在反应世界中是不同的东西。解决问题的最快方法是替换它:
this.setState({
trip: trip,
isLoading: false,
initialValues: trip
});
对于:
this.props.initialize(trip)
道具 initialize
由 redux-form 导出到您的组件以更新表单初始状态。我做了一个 codesandbox 在那里你可以检查它是否工作。
也就是说,我认为您应该更改组件的结构,而不是将数据加载到组件 (componentDidMount) 中,您应该在 redux 操作中执行它,然后更新您的状态。这样做,您可以轻松地从 mapStateToProps
函数上的 redux 状态获取表单数据,并设置 initialValues
prop 而不是使用 initialize
props,这要好得多。
我正在使用带有 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 方法的状态。那么,我在这里做错了什么?
首先,您试图通过 this.setState
传递 initialValues
这是行不通的,reduxForm 期望 initialValues
作为 props
传递。
有一点要提一下,application state
和component 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 所说,您的错误是您试图通过 setState
更改 prop
,它们在反应世界中是不同的东西。解决问题的最快方法是替换它:
this.setState({
trip: trip,
isLoading: false,
initialValues: trip
});
对于:
this.props.initialize(trip)
道具 initialize
由 redux-form 导出到您的组件以更新表单初始状态。我做了一个 codesandbox 在那里你可以检查它是否工作。
也就是说,我认为您应该更改组件的结构,而不是将数据加载到组件 (componentDidMount) 中,您应该在 redux 操作中执行它,然后更新您的状态。这样做,您可以轻松地从 mapStateToProps
函数上的 redux 状态获取表单数据,并设置 initialValues
prop 而不是使用 initialize
props,这要好得多。