J'ai des problèmes avec la définition des valeurs de champ de formulaire initial à l'aide de redux-form.
J'utilise redux-form v6.0.0-rc.3 et réagis v15.3.0.
Voici donc mon problème, j'ai une grille d'utilisateurs et quand une ligne d'utilisateur est cliquée, je navigue vers une page de modification des utilisateurs et j'inclus l'ID des utilisateurs dans l'url. Ensuite, sur la page de modification des utilisateurs, j'attrape l'ID et appelle fetchUser (this.props.params.id) qui est un créateur d'action qui renvoie this.state.users. J'essaie ensuite de définir les valeurs initiales des formulaires en appelant:
function mapStateToProps(state) {
return { initialValues: state.users.user }
}
D'après ce que je comprends, cela devrait définir les valeurs initiales sur state.users.user et chaque fois que cet état est mis à jour, les valeurs initiales doivent également être mises à jour. Ce n'est pas le cas pour moi. InitialValues est défini sur la ligne utilisateur sur laquelle l'utilisateur a cliqué précédemment (c'est-à-dire l'état précédent pour this.state.users.user). J'ai donc décidé de tester cela et d'ajouter un bouton à ce composant et lorsque vous cliquez dessus, j'appelle à nouveau fetchUser avec un ID utilisateur codé en dur:
this.props.fetchUser('75e585aa-480b-496a-b852-82a541aa0ca3');
Cela met à jour l'état correctement mais les valeurs pour initialValues ne changent pas. Il n'est pas mis à jour lorsque l'état est mis à jour. J'ai testé exactement ce même processus sur une ancienne version de redux-form et cela a fonctionné comme prévu.
Suis-je en train de faire quelque chose de mal ici ou est-ce un problème avec la version que j'utilise.
Formulaire de modification des utilisateurs -
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
Réducteur d'utilisateurs -
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;
}
}
Indice de réduction -
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;
J'étais confronté au même problème après la mise à jour vers redux-form v6.0.0-rc.4.
J'ai résolu le paramètre enableReinitialize sur true
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true
})(UsersShowForm)
Pour pré-remplir un formulaire redux-form
Avec les données d'une ressource, vous utiliseriez le prop initialValues
qui est lu automatiquement lors de la décoration du composant/conteneur avec le connecteur reduxForm
. Il est important que les clés dans initialValues
correspondent à name
dans les champs du formulaire.
Remarque: Il est nécessaire d'appliquer d'abord le reduxForm()
décorateur, puis le connect()
de redux. Cela ne fonctionnera pas dans l'autre sens.
Utilisation de 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)
De la documentation officielle:
Les valeurs fournies au paramètre initialValues prop ou au paramètre de configuration reduxForm () seront chargées dans l'état de formulaire et traitées par la suite comme "primitives". Ce seront également les valeurs qui seront retournées lorsque reset () sera distribué. En plus d'enregistrer les valeurs "vierges", l'initialisation de votre formulaire remplacera toutes les valeurs existantes.
Trouvez plus d'informations et un exemple complet dans le documentation officielle
Dans mon cas, j'ai Redux Form, 2 Route avec de petits changements de paramètres d'URL. Lors de la commutation entre les composants, les accessoires n'étaient pas mis à jour. Il ne cessait de montrer un formulaire vierge.
Exemple: baseurl/:id/personal -> baseurl/:id/employment
Après le débogage, j'ai constaté que mapStateToProps ne se déclenche pas lorsque les valeurs initiales sont définies.
<React.Fragment>
<Route
exact={true}
path="/path1"
component={PersonalDetails}
key="personal"
/>
<Route
exact={true}
path="/path1/employment"
component={Employment}
key="employment"
/>
</React.Fragment>
définir destroyOnUnmount sur false mapStateToProps a résolu mon problème, où sa valeur par défaut est true .
enableReinitialize: true,
destroyOnUnmount: false
Exemple utilisant ci-dessus:
UsersShowForm = reduxForm({
form: 'UsersShowForm',
enableReinitialize: true,
destroyOnUnmount: false
})(UsersShowForm)
En savoir plus: destroyOnMount