const App = () => { const [User, setUser] = useState({ id: 1, name: "ed", age: Number, edit: false }); return ( <div> <input value={User.name} onChange={e => setUser.name(e.target.value)} /> </div> ); }; I am working with react hooks. I set the initial state to an object. I try changing the value with react hooks but this gives an error TypeError: setUser.name is not a function
3 Réponses :
setUser
est une fonction que vous utilisez pour mettre à jour l'état et comme il remplace simplement l'état dont vous avez besoin pour fusionner également votre valeur d'état précédente. L'événement est également effacé dans le rappel, vous devez donc obtenir la valeur avant d'utiliser le rappel de setUser. Il est préférable d'écrire une fonction de gestionnaire pour cela. Vous pouvez également écrire une fonction générique pour gérer la définition de toutes les valeurs
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="app" />
const App = () => { const [User, setUser] = React.useState({ id: 1, name: "ed", age: Number, edit: false }); const handleChange = (e) => { const {value, name} = e.target; setUser(prev => ({...prev, [name]: val})) } return ( <div> <input value={User.name} onChange={handleChange} /> </div> ); }; ReactDOM.render(<App />, document.getElementById('app'));
Obtention de cette erreur: TypeError: impossible de lire la propriété 'value' de null
@Navish Avez-vous créé le gestionnaire comme je l'ai suggéré, vous devez lire la valeur avant le rappel du programme de mise à jour de l'état, sinon il sera effacé
setUser
est une fonction identique à setState
.. pour plus de détails, consultez hooks
const App = () => { const [User, setUser] = useState({ id: 1, name: "ed", age: Number, edit: false }); return ( <div> <input value={User.name} onChange={e => setUser(prev => ({...prev, name: e.target.value}))} /> ); };
dans votre contexte:
<input value={User.name} onChange={e => setUser(prev => ({...prev, name: e.target.value}))} />
Regardons la valeur de User et setUser
function App() { const [user, setUser] = useObjState({ id: 1, name: "ed", age: Number, edit: false }); return ( <input value={user.name} onChange={e => setUser.name(e.target.value)} /> /> ) }
React.useState
renvoie une valeur et un setter à cette valeur. setUser
est une fonction. Ainsi, alors que User.name est une chaîne avec la valeur initiale "ed", setUser.name n'existe pas. L'erreur TypeError: setUser.name n'est pas une fonction
est le résultat d'une tentative de passer une valeur indéfinie en argument. Une façon de résoudre ce problème est comme le suggèrent Murtaza Hussain et d'autres réponses:
const useObjState = initialObj => { const [obj, setObj] = React.useState(initialObj); const setObjHelper = useMemo( () => { // the value of setObjHelper is permanent, so even if it is passed to a child component, it shouldn't require extra component updates const helper = {} Object.keys(initialObj).forEach(key => { helper[key] = newVal => setObj({ ...obj, [key]: newVal }); }); return helper }, []) return [obj, setObjHelper]; };
Comme alternative, vous pouvez utiliser un hook useObjState
personnalisé, qui fournit un API assez simple.
<input value={User.name} onChange={e => setUser(prev => ({...prev, name: e.target.value}))} />
Il fournit un moyen beaucoup plus simple / plus propre de mettre à jour la valeur de la propriété name.
const [User, setUser] = useState({ id: 1, name: "ed", age: Number, edit: false });
Démo p>
Salut Ben, cela ne répond pas à la question initiale, cela suggère une alternative. Je mettrais cela comme un commentaire et non comme une réponse, car quelqu'un pourrait marquer ou voter contre. Juste mon avis. C'est une excellente suggestion, mais pas une réponse à la question de savoir pourquoi il obtient une erreur sur le code qu'il a écrit spécifiquement.
@EricBishard, merci pour votre commentaire. Je suis d'accord. J'ai fait quelques ajustements pour mieux répondre à la question. Jetez un œil et faites-moi savoir si vous pensez toujours qu'il y a un problème.
setUser
est une fonction et non un objet, c'est ce que vous essayez de faire. il suffit de le changer ensetUser ((prevState) => {... prevState, name: e.target.value)} />