我试图映射一个redux-form的initialValues
属性,以便可以预先填充表单(这是一个从外部API填充的用户配置文件编辑屏幕)
由于验证了允许用户管理哪些字段,因此在填充初始值时,React JS前端需要尽可能动态。我在上找到了另一个关于动态预填充initialValues
(Dynamically load initialValues in Redux Form)的问题,但该解决方案仅适用于没有嵌套的对象。不幸的是,我对API 的回复包含了一些嵌套:
{
"id": 1,
"email": "admin@test.com",
"location_id": 2,
"created_at": "2017-09-08 19:55:01",
"updated_at": "2017-09-08 19:55:01",
"can_edit": [ // <-- this array contains all the fields that the given user is allowed to edit on the given profile.
"profile_img", // <-- possibly this could be rewritten to return for example 'profile.profile_img' rather than just 'profile_img', but not sure how that could help
"password" // <-- not returned in the actual user object for obvious reasons, but there is logic for displaying the password field anyway
],
"profile": {
"user_id": 1,
"first_name": "Admin",
"last_name": "Test",
"profile_img": "https://pbs.twimg.com/profile_images/449750767281254400/M_ukevnA.jpeg",
"position": "Admin",
"created_at": "2017-09-13 11:38:49",
"updated_at": "2017-09-13 11:38:49",
},
"location": {
"id": 2,
"text": "Test Location",
"lang": "en",
"created_at": "2017-09-13 11:35:41",
"updated_at": "2017-09-13 11:35:41",
"deleted_at": null
}
}
因此,我无法直接填充initialValues - 例如,可能的可编辑字段包括root用户对象的email
或location_id
或first_name
,嵌套配置文件对象的last_name
或profile_img
属性。
作为参考,我的EditProfile组件位于下方(截断为相关部分)。
class EditProfile extends Component {
/**
* Static property types.
*/
static propTypes = {
...
}
/**
* Renders editable profile fields.
*/
profileFields(user) {
if(!this.state.currentField.length){
this.state.currentField = user.can_edit[0]
}
let fields = user.can_edit.map((can_edit) => {
switch(can_edit){
// render an email input
case 'email':
return (
<ProfileFieldGroup key={can_edit} show={ this.state.currentField == can_edit }>
<label htmlFor="email">Email</label>
<Field
name="email"
id="email"
type="email"
component="input"
value={ user.email }
/>
</ProfileFieldGroup>
)
// render a group of password inputs
case 'password':
return (
<ProfileFieldGroup key={can_edit} show={ this.state.currentField == can_edit }>
<label htmlFor="old_password">Old Password</label>
<Field
name="old_password"
id="old_password"
type="password"
component="input"
/>
<label htmlFor="password">New Password</label>
<Field
name="password"
id="password"
type="password"
component="input"
/>
<label htmlFor="password_confirm">Confirm New Password</label>
<Field
name="password_confirm"
id="password_confirm"
type="password"
component="input"
/>
</ProfileFieldGroup>
)
// by default, create a text input whose ID and name match the given property
default:
console.log(user.profile[can_edit])
return (
<ProfileFieldGroup key={can_edit} show={ this.state.currentField == can_edit }>
<label htmlFor={can_edit}>{ humanizeText(can_edit) }</label>
<Field
name={ can_edit }
id={ can_edit }
type="text"
component="input"
value={ user.profile[can_edit] }
/>
</ProfileFieldGroup>
)
}
})
return (
<div>
{ fields }
</div>
)
}
/**
* Handles the submit event.
* This function is mainly managed by Redux.
*/
submit = (values) => {
...
}
/**
* Renders the component.
*/
render() {
const {
handleSubmit,
user: user,
save: save
} = this.props
return (
<section>
<header>
<h1>Edit User</h1>
</header>
<div className="main">
<form onSubmit={ handleSubmit(this.submit) }>
{user.successful && !user.requesting &&
this.profileFields(user.user)
}
{user.requesting && !user.successful && (
<img className="loader" src=""/>
)}
</form>
</div>
<footer>
</footer>
</section>
)
}
}
然后连接到redux:
const mapStateToProps = state => ({
user: state.user,
save: state.save,
initialValues: state.user.user // <-- this right here
})
const connected = connect(mapStateToProps, { apiGetRequest,
apiPostRequest })(EditProfile)
const formed = reduxForm({
form: 'editprofile',
})(connected)
总结:如何从潜在的嵌套对象动态填充redux表单的initialValues属性?这样的事情几乎可能吗?
答案 0 :(得分:0)
如何从潜在的嵌套对象动态填充redux表单的initialValues属性?这样的事情几乎可能吗?
是的,这是可能的。如果您从API接收嵌套数据,根据documentation,您可以在name
道具中设置关键路径:
function Form ({ handleSubmit }) {
return (
<form onSubmit={handleSubmit}>
// ...
<Field name="my.nested.prop" ... />
</form>
)
}