Je travaille actuellement sur un formulaire d'inscription et voici un extrait de mon code:
const Signup = () => {
const [username, setUsername] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [passwordConfirmation, setPasswordConfirmation] = useState('')
const clearState = () => {
setUsername('')
setEmail('')
setPassword('')
setPasswordConfirmation('')
}
const handleSubmit = signupUser => e => {
e.preventDefault()
signupUser().then(data => {
console.log(data)
clearState() // <-----------
})
}
return <JSX />
}
export default Signup
Chaque élément d'état est utilisé pour une entrée contrôlée pour le formulaire.
Essentiellement, ce que je veux faire, c'est après que l'utilisateur s'est inscrit avec succès, je veux que l'état revienne à l'état initial avec les champs effacés.
Il est impératif de remettre manuellement chaque état dans des chaînes vides dans clearState
Je me demandais s'il y avait une méthode ou une fonction fournie avec React qui réinitialise l'état à son état initial) Valeurs initiales?
Malheureusement, il n'existe aucun moyen intégré de définir l'état à sa valeur initiale.
Votre code semble bon, mais si vous souhaitez réduire les fonctions nécessaires, vous pouvez placer l'intégralité de votre état de formulaire dans un seul objet variable d'état et réinitialiser à l'objet initial.
Exemple
const { useState } = React;
function signupUser() {
return new Promise(resolve => {
setTimeout(resolve, 1000);
});
}
const initialState = {
username: "",
email: "",
password: "",
passwordConfirmation: ""
};
const Signup = () => {
const [
{ username, email, password, passwordConfirmation },
setState
] = useState(initialState);
const clearState = () => {
setState({ ...initialState });
};
const onChange = e => {
const { name, value } = e.target;
setState(prevState => ({ ...prevState, [name]: value }));
};
const handleSubmit = e => {
e.preventDefault();
signupUser().then(clearState);
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input value={username} name="username" onChange={onChange} />
</label>
</div>
<div>
<label>
Email:
<input value={email} name="email" onChange={onChange} />
</label>
</div>
<div>
<label>
Password:
<input
value={password}
name="password"
type="password"
onChange={onChange}
/>
</label>
</div>
<div>
<label>
Confirm Password:
<input
value={passwordConfirmation}
name="passwordConfirmation"
type="password"
onChange={onChange}
/>
</label>
</div>
<button>Submit</button>
</form>
);
};
ReactDOM.render(<Signup />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
Je pense que la réponse votée est toujours correcte, mais récemment React a publié le nouveau useReducer
intégré qui, selon leurs propres mots, est
pratique pour réinitialiser l'état plus tard en réponse à une action
https://reactjs.org/docs/hooks-reference.html#usereducer
Il indique également qu'il est généralement préférable d'utiliser useReducer lorsque vous avez une logique d'état complexe qui implique plusieurs sous-valeurs ou lorsque l'état suivant dépend du précédent.
En utilisant le même échantillon sur la réponse votée, vous pouvez utiliser useReducer comme ceci:
import React, { useReducer } from "react";
const initialState = {
username: "",
email: "",
password: "",
passwordConfirmation: "",
};
const reducer = (state, action) => {
if (action.type === "reset") {
return initialState;
}
const result = { ...state };
result[action.type] = action.value;
return result;
};
const Signup = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const { username, email, password, passwordConfirmation } = state;
const handleSubmit = e => {
e.preventDefault();
/* fetch api */
/* clear state */
dispatch({ type: "reset" });
};
const onChange = e => {
const { name, value } = e.target;
dispatch({ type: name, value });
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input value={username} name="username" onChange={onChange} />
</label>
</div>
<div>
<label>
Email:
<input value={email} name="email" onChange={onChange} />
</label>
</div>
<div>
<label>
Password:
<input
value={password}
name="password"
type="password"
onChange={onChange}
/>
</label>
</div>
<div>
<label>
Confirm Password:
<input
value={passwordConfirmation}
name="passwordConfirmation"
type="password"
onChange={onChange}
/>
</label>
</div>
<button>Submit</button>
</form>
);
};
export default Signup;
import React, { FC, Reducer, useReducer } from "react";
interface IState {
email: string;
password: string;
passwordConfirmation: string;
username: string;
}
interface IAction {
type: string;
value?: string;
}
const initialState: IState = {
email: "",
password: "",
passwordConfirmation: "",
username: "",
};
const reducer = (state: IState, action: IAction) => {
if (action.type === "reset") {
return initialState;
}
const result: IState = { ...state };
result[action.type] = action.value;
return result;
};
export const Signup: FC = props => {
const [state, dispatch] = useReducer<Reducer<IState, IAction>, IState>(reducer, initialState, () => initialState);
const { username, email, password, passwordConfirmation } = state;
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
/* fetch api */
/* clear state */
dispatch({ type: "reset" });
};
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
dispatch({ type: name, value });
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Username:
<input value={username} name="username" onChange={onChange} />
</label>
</div>
<div>
<label>
Email:
<input value={email} name="email" onChange={onChange} />
</label>
</div>
<div>
<label>
Password:
<input
value={password}
name="password"
type="password"
onChange={onChange}
/>
</label>
</div>
<div>
<label>
Confirm Password:
<input
value={passwordConfirmation}
name="passwordConfirmation"
type="password"
onChange={onChange}
/>
</label>
</div>
<button>Submit</button>
</form>
);
};
Notez que j'ai créé cette fonction reducer
const pour qu'elle soit aussi générique que possible, mais vous pouvez la changer complètement et tester différents types d'actions (autres que simplement indiquer les noms de propriétés) et effectuer des calculs complexes avant de renvoyer l'état modifié. Il y a quelques exemples dans le lien fourni ci-dessus.
Comme je le sais (en lisant les documents React) - il n'y a aucun moyen de le faire pour l'instant.
Vous pouvez utiliser une variable d'état comme décrit dans le FAQ ici: https://reactjs.org/docs/hooks-faq.html#should-i-use-one- ou-plusieurs-états-variables
Cela dépend bien sûr de votre cas d'utilisation.
La recomposition du composant à partir du conteneur parent le réinitialisera également automatiquement, bien sûr.
Parallèlement aux autres réponses, je recommanderais de prendre une bibliothèque d'aide comme celle-ci , ou de faire votre propre abstraction au-dessus des crochets, si c'est quelque chose que vous ferez souvent.
useState
et amis ne sont en fait que des primitives de bas niveau pour vous, l'utilisateur, pour créer des crochets plus utiles par-dessus. J'ai des projets où les appels bruts useState
sont en fait assez rares.
Vous auriez pu utiliser useRef dans les crochets quelque chose comme ça
const myForm = useRef(null)
const submit = () => {
myForm.current.reset(); // will reset the entire form :)
}
<form ref={myForm} onSubmit={submit}>
<input type="text" name="name" placeholder="John Doe">
<input type="email" name="name" placeholder="[email protected]">
<button type="submit">Submit</button>
</form>
J'ai totalement accepté la réponse de @ Tholle.
Si vous devez exécuter certaines fonctions après la suppression de l'état
const clearState = () => {
setState({...initialState});
return {
foo,
bar,
// ...
};
};
// when component is unmounted
() => clearState().foo();
() => clearState().bar();
C'est ainsi que vous pouvez réinitialiser valeurs d'entrée (à partir de l'objet) dans hooks après la soumission du formulaire.
Vous pouvez définir plusieurs valeurs d'entrée dans le même useState
comme firstName, lastName, etc ...
const [state, setState] = React.useState({ firstName: "", lastName: "" });
Exemple de code.
export default function App() {
const [state, setState] = React.useState({ firstName: "", lastName: "" });
const handleSubmit = e => {
e.preventDefault();
setState({firstName:'',lastName:''})
};
const handleChange = e => {
const { name, value } = e.target;
setState({ ...state, [name]: value });
};
console.log(state)
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="firstName"
placeholder="Enter first name"
value={state.firstName}
onChange={handleChange}
/>
<input
type="text"
name="lastName"
placeholder="Enter last name"
value={state.lastName}
onChange={handleChange}
/>
<input type="submit" value="Submit" />
</form>
);
}
Si vous souhaitez que plusieurs entrées soient définies dans l'objet au lieu de déclarer séparément.
J'ai eu un cas d'utilisation similaire. Complètement indépendant d'un mécanisme de connexion, d'inscription, mais je l'ai modifié pour qu'il soit lié à votre cas d'utilisation.
À mon avis, un moyen facile de résoudre ce problème est d'utiliser un composant parent.
const initUser = {
name: '',
email: '',
password: '',
passwordConfirmation: ''
}
const LoginManager = () => {
const [user, setUser] = useState(initUser)
return <Signup user={user} resetUser={setUser} />
}
const Signup = ({user, resetUser}) => {
const [username, setUsername] = useState(user.name)
const [email, setEmail] = useState(user.email)
const [password, setPassword] = useState(user.password)
const [passwordConfirmation, setPasswordConfirmation] = useState(user.passwordConfirmation)
const handleSubmit = signupUser => e => {
e.preventDefault()
signupUser().then(data => {
console.log(data)
resetUser(initUser) // <-----------
})
}
return <JSX />
}
export default Signup