J'essaye d'étudier les hooks de réaction
. il s'agit d'un formulaire d'inscription qui fonctionne bien lorsque vous utilisez le composant de classe classique avec un état interne et des formulaires contrôlés. mais quand j'essaye d'utiliser des hooks de réaction
comme celui-ci et de taper sur l'entrée cela n'affichera tout simplement pas ce que je saisis .
J'ai consigné l'événement et j'ai réalisé que le problème pourrait être que la valeur cible est nulle. Quelqu'un peut-il m'expliquer pourquoi cela pourrait être le cas?
const SignUp = props => { const [displayName, setDisplayName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const handleChange = e => { console.log(e); const { name, value } = e.target; switch (name) { case name === "displayName": setDisplayName(value); case name === "email": setEmail(value); case name === "password": setPassword(value); case name === "confirmPassword": setConfirmPassword(value); } }; const handleSubmit = async e => { console.log(e); e.preventDefault(); if (password !== confirmPassword) { alert("passwords do not match"); return; } const { signUpStart } = props; signUpStart({ email, password, displayName }); }; return ( <div className="sign-up-section"> <form onSubmit={handleSubmit}> <FormInput type="text" name="displayName" handleChange={handleChange} value={displayName} label="display name" /> <FormInput type="email" required name="email" value={email} handleChange={handleChange} label="email" /> <FormInput type="password" name="password" handleChange={handleChange} value={password} label="password" /> <FormInput type="psssword" name="confirmPassword" handleChange={handleChange} value={confirmPassword} label="comfirmPassword" /> <Button type="submit" name="password" label="SIGN" /> </form> </div> ); }; const FormInput =({label,handleChange, ...otherProps})=>{ return <div className='group'> <input {...otherProps} onChange={handleChange} className='form-input'/> { label?(<label className={`${otherProps.value.length? 'shrink':''} form-input-label` }>{label}</label>):null } </div> }
3 Réponses :
https://stackblitz.com/edit/react-form-hooks vous voulez setState pour chaque changement dans le champ d'entrée, de sorte que la fonction de rappel onChange sera appelée chaque fois qu'il y a une modification dans le champ d'entrée.
en venant à votre fonction de rappel, le cas du commutateur devrait être comme ceci:
switch(cond){ case 'cond1': execute; break; }
l'instruction switch est après avoir enregistré l'événement et découvert que e.target est nul. Savez-vous pourquoi e.target est nul, mais ce n'est pas le cas lorsque je passe au composant de classe?
e.target n'est pas nul, ouvrez le lien et continuez à taper sur n'importe quelle balise d'entrée et ouvrez la console pour vérifier.
Avez-vous essayé d'utiliser e.currentTarget
à la place?
const { name, value } = e.currentTarget;
Cela garantira que vous obtiendrez l'élément auquel l'écouteur d'événements est attaché. p >
Voir: Quel est le différence entre la propriété currentTarget et la propriété cible en javascript
l'utilisation de l'instruction switch semblait résoudre le problème mais merci pour cette ressource.
Comme vous pouvez le voir ci-dessous, le problème n'est pas que e.target
est nul ou non défini. Le problème est en fait dans votre instruction switch.
Vous mélangez ici la syntaxe de switch
et if else
case name === "displayName":
. Le commutateur effectue automatiquement la partie name ==
. Dans votre cas, tout ce que vous avez à faire est de mettre ce que nom
doit être égal à - pas l'expression entière.
Changez comme indiqué ci-dessous, avec la casse code> et avec
break
après la mise à jour de l'état.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>
const {useState, useEffect} = React; const SignUp = props => { const [displayName, setDisplayName] = useState(""); const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const handleChange = e => { console.log(e.target.name); // Logs correctly console.log(e.target.value); // Logs correctly const { name, value } = e.target; switch (name) { case "displayName": setDisplayName(value); break; case "email": setEmail(value); break; case "password": setPassword(value); break; case "confirmPassword": setConfirmPassword(value); break; } }; const handleSubmit = e => { console.log(e); e.preventDefault(); if (password !== confirmPassword) { alert("passwords do not match"); return; } const { signUpStart } = props; //signUpStart({ email, password, displayName }); }; return ( <div> <form onSubmit={handleSubmit}> <FormInput type="text" name="displayName" handleChange={handleChange} value={displayName} label="display name" /> <FormInput type="email" required name="email" value={email} handleChange={handleChange} label="email" /> <FormInput type="password" name="password" handleChange={handleChange} value={password} label="password" /> <FormInput type="psssword" name="confirmPassword" handleChange={handleChange} value={confirmPassword} label="comfirmPassword" /> <button type="submit" name="password">Sign</button> </form> </div> ); }; const FormInput = ({label,handleChange, ...otherProps}) => { return ( <div> <input {...otherProps} onChange={handleChange} className='form-input' /> {label ? <label>{label}</label> : null} </div> ); } ReactDOM.render(<SignUp />, document.getElementById('root'));
Wow. Merci mec. Je me cognais la tête contre le mur. Je ne pouvais tout simplement pas comprendre pourquoi cela ne fonctionnait pas.
Qu'est-ce que
FormInput
? Est-ce une bibliothèque?c'est un composant d'entrée personnalisé. le composant d'inscription lui transmet des gestionnaires d'événements comme accessoires
Pouvez-vous le montrer?
e.target
devrait être défini, mais l'entrée personnalisée pourrait lui faire quelque chose.j'ai modifié la question pour inclure l'entrée personnalisée