Redux 表单 - initialValues 不随状态更新
Redux Form - initialValues not updating with state
我在使用 redux-form 设置初始表单字段值时遇到一些问题。
我正在使用 redux-form v6.0.0-rc.3 和 react v15.3.0。
所以这是我的问题,我有一个用户网格,当单击用户行时,我导航到编辑用户页面并将用户 ID 包含在 url 中。然后在编辑用户页面上,我获取 ID 并调用 fetchUser(this.props.params.id),它是 returns this.state.users 的动作创建者。然后我试图通过调用来设置表单初始值:
function mapStateToProps(state) {
return { initialValues: state.users.user }
}
据我了解,这应该将 initialValues 设置为 state.users.user,并且每当更新此状态时,也应更新 initialValues。我不是这种情况。 InitialValues 被设置为先前单击的用户行(即 this.state.users.user 的先前状态)。所以我决定对此进行测试并向该组件添加一个按钮,当它被点击时我再次调用 fetchUser 并使用硬编码的用户 ID:
this.props.fetchUser('75e585aa-480b-496a-b852-82a541aa0ca3');
这是正确更新状态,但 initialValues 的值没有改变。更新状态时它不会更新。我在旧版本的 redux-form 上测试了这个完全相同的过程,它按预期工作。
我是不是做错了什么,还是我使用的版本有问题。
用户编辑表单 -
class UsersShowForm extends Component {
componentWillMount() {
this.props.fetchUser(this.props.params.id);
}
onSubmit(props){
console.log('submitting');
}
changeUser() {
this.props.fetchUser('75e585aa-480b-496a-b852-82a541aa0ca3');
}
renderTextField(field) {
return (
<TextField
floatingLabelText={field.input.label}
errorText={field.touched && field.error}
fullWidth={true}
{...field.input}
/>)
}
render() {
const { handleSubmit, submitting, pristine } = this.props;
return(
<div>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))} className="mdl-cell mdl-cell--12-col">
<Field name="emailAddress" component={this.renderTextField} label="Email Address"/>
<Field name="firstName" component={this.renderTextField} label="First Name"/>
<Field name="lastName" component={this.renderTextField} label="Last Name"/>
</form>
<RaisedButton onClick={this.changeUser.bind(this)} label="Primary" primary={true} />
</div>
);
}
}
function mapStateToProps(state) {
return { initialValues: state.users.user }
}
UsersShowForm = reduxForm({
form: 'UsersShowForm'
})(UsersShowForm)
UsersShowForm = connect(
mapStateToProps,
actions
)(UsersShowForm)
export default UsersShowForm
用户减速器 -
import {
FETCH_USERS,
FETCH_USER
} from '../actions/types';
const INITIAL_STATE = { all: [], user: {} };
export default function(state = { INITIAL_STATE }, action) {
switch (action.type) {
case FETCH_USERS:
return {...state, all: action.payload };
case FETCH_USER:
return {...state, user: action.payload };
default:
return state;
}
}
Reducer 索引 -
import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
import usersReducer from './users_reducer';
const rootReducer = combineReducers({
form: formReducer,
users: usersReducer
});
export default rootReducer;
更新到 redux-form v6.0.0-rc.4 后我遇到了同样的问题。
我解决了将 enableReinitialize 设置为 true
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true
})(UsersShowForm)
要 pre-fill 一个包含资源数据的 redux-form
表单,您可以使用 initialValues
属性,它在用 [= 装饰 component/container 时自动读取13=] 连接器。 initialValues
中的键与表单字段中的 name
匹配很重要。
注意:需要先应用reduxForm()
装饰器,然后是redux的connect()
。反之则不行。
使用 redux-form 7.2.3:
const connectedReduxForm = reduxForm({
form: 'someUniqueFormId',
// resets the values every time the state changes
// use only if you need to re-populate when the state changes
//enableReinitialize : true
})(UserForm);
export default connect(
(state) => {
// map state to props
// important: initialValues prop will be read by redux-form
// the keys must match the `name` property of the each form field
initialValues: state.user
},
{ fetchUser } // map dispatch to props
)(connectedReduxForm)
来自官方文档:
Values provided to the initialValues prop or reduxForm() config parameter will be loaded into the form state and treated thereafter as "pristine". They will also be the values that will be returned to when reset() is dispatched. In addition to saving the "pristine" values, initializing your form will overwrite any existing values.
中查找更多信息和完整示例
在我的例子中,我有 Redux Form,2 条路线 url param 变化很小。
当在组件道具之间切换时没有得到更新。
一直显示空白。
示例:baseurl/:id/personal -> baseurl/:id/employment
调试后我发现 mapStateToProps 有时在设置初始值的地方没有触发。
<React.Fragment>
<Route
exact={true}
path="/path1"
component={PersonalDetails}
key="personal"
/>
<Route
exact={true}
path="/path1/employment"
component={Employment}
key="employment"
/>
</React.Fragment>
将 destroyOnUnmount 设置为 false mapStateToProps 解决了我的问题,它的默认值为 true。
enableReinitialize: true,
destroyOnUnmount: false
上面的例子:
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true,
destroyOnUnmount: false
})(UsersShowForm)
阅读更多:destroyOnMount
我在使用 redux-form 设置初始表单字段值时遇到一些问题。
我正在使用 redux-form v6.0.0-rc.3 和 react v15.3.0。
所以这是我的问题,我有一个用户网格,当单击用户行时,我导航到编辑用户页面并将用户 ID 包含在 url 中。然后在编辑用户页面上,我获取 ID 并调用 fetchUser(this.props.params.id),它是 returns this.state.users 的动作创建者。然后我试图通过调用来设置表单初始值:
function mapStateToProps(state) {
return { initialValues: state.users.user }
}
据我了解,这应该将 initialValues 设置为 state.users.user,并且每当更新此状态时,也应更新 initialValues。我不是这种情况。 InitialValues 被设置为先前单击的用户行(即 this.state.users.user 的先前状态)。所以我决定对此进行测试并向该组件添加一个按钮,当它被点击时我再次调用 fetchUser 并使用硬编码的用户 ID:
this.props.fetchUser('75e585aa-480b-496a-b852-82a541aa0ca3');
这是正确更新状态,但 initialValues 的值没有改变。更新状态时它不会更新。我在旧版本的 redux-form 上测试了这个完全相同的过程,它按预期工作。
我是不是做错了什么,还是我使用的版本有问题。
用户编辑表单 -
class UsersShowForm extends Component {
componentWillMount() {
this.props.fetchUser(this.props.params.id);
}
onSubmit(props){
console.log('submitting');
}
changeUser() {
this.props.fetchUser('75e585aa-480b-496a-b852-82a541aa0ca3');
}
renderTextField(field) {
return (
<TextField
floatingLabelText={field.input.label}
errorText={field.touched && field.error}
fullWidth={true}
{...field.input}
/>)
}
render() {
const { handleSubmit, submitting, pristine } = this.props;
return(
<div>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))} className="mdl-cell mdl-cell--12-col">
<Field name="emailAddress" component={this.renderTextField} label="Email Address"/>
<Field name="firstName" component={this.renderTextField} label="First Name"/>
<Field name="lastName" component={this.renderTextField} label="Last Name"/>
</form>
<RaisedButton onClick={this.changeUser.bind(this)} label="Primary" primary={true} />
</div>
);
}
}
function mapStateToProps(state) {
return { initialValues: state.users.user }
}
UsersShowForm = reduxForm({
form: 'UsersShowForm'
})(UsersShowForm)
UsersShowForm = connect(
mapStateToProps,
actions
)(UsersShowForm)
export default UsersShowForm
用户减速器 -
import {
FETCH_USERS,
FETCH_USER
} from '../actions/types';
const INITIAL_STATE = { all: [], user: {} };
export default function(state = { INITIAL_STATE }, action) {
switch (action.type) {
case FETCH_USERS:
return {...state, all: action.payload };
case FETCH_USER:
return {...state, user: action.payload };
default:
return state;
}
}
Reducer 索引 -
import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
import usersReducer from './users_reducer';
const rootReducer = combineReducers({
form: formReducer,
users: usersReducer
});
export default rootReducer;
更新到 redux-form v6.0.0-rc.4 后我遇到了同样的问题。
我解决了将 enableReinitialize 设置为 true
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true
})(UsersShowForm)
要 pre-fill 一个包含资源数据的 redux-form
表单,您可以使用 initialValues
属性,它在用 [= 装饰 component/container 时自动读取13=] 连接器。 initialValues
中的键与表单字段中的 name
匹配很重要。
注意:需要先应用reduxForm()
装饰器,然后是redux的connect()
。反之则不行。
使用 redux-form 7.2.3:
const connectedReduxForm = reduxForm({
form: 'someUniqueFormId',
// resets the values every time the state changes
// use only if you need to re-populate when the state changes
//enableReinitialize : true
})(UserForm);
export default connect(
(state) => {
// map state to props
// important: initialValues prop will be read by redux-form
// the keys must match the `name` property of the each form field
initialValues: state.user
},
{ fetchUser } // map dispatch to props
)(connectedReduxForm)
来自官方文档:
中查找更多信息和完整示例Values provided to the initialValues prop or reduxForm() config parameter will be loaded into the form state and treated thereafter as "pristine". They will also be the values that will be returned to when reset() is dispatched. In addition to saving the "pristine" values, initializing your form will overwrite any existing values.
在我的例子中,我有 Redux Form,2 条路线 url param 变化很小。 当在组件道具之间切换时没有得到更新。 一直显示空白。
示例:baseurl/:id/personal -> baseurl/:id/employment
调试后我发现 mapStateToProps 有时在设置初始值的地方没有触发。
<React.Fragment>
<Route
exact={true}
path="/path1"
component={PersonalDetails}
key="personal"
/>
<Route
exact={true}
path="/path1/employment"
component={Employment}
key="employment"
/>
</React.Fragment>
将 destroyOnUnmount 设置为 false mapStateToProps 解决了我的问题,它的默认值为 true。
enableReinitialize: true,
destroyOnUnmount: false
上面的例子:
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true,
destroyOnUnmount: false
})(UsersShowForm)
阅读更多:destroyOnMount