J'essaie de passer et de mettre à jour un état avec useContext ;

App.js

import Home from './components/Home'
const UserContext = createContext();

function App() {
  const [name, setName] = useState('Name');

  return (
      <UserContext.Provider value={{name, setName}}>
        <Home/>
      </UserContext.Provider>
  );
}

export default App;

Home.js

import UserContext from '../../App'

function Home() {
    const user = useContext(UserContext);

    return (
        <>
        <label>Your name:</label>
        <input type='text' onChange={e => user.setName(e.target.value)} />
        <p>{user.name}</p>
        </>
    )
}

export default Home;

Je reçois cette erreur

TypeError : Impossible de lire les propriétés de non défini (lecture de 'nom') ;

Comment passer correctement l'état entre les composants avec useContext ?

1
Sasquatch 2 oct. 2021 à 22:59

2 réponses

Meilleure réponse

Vous devez exporter votre UserContext, afin qu'il puisse être importé dans les composants qui en ont besoin :

export const UserContext = React.createContext();

function App() {
  const [name, setName] = useState('Name');

  return (
    <UserContext.Provider value={{ name, setName }}>
      <Home />
    </UserContext.Provider>
  );
}

Ensuite, vous pouvez l'importer dans votre composant App :

import { UserContext } '../../App'

function Home() {
    const user = useContext(UserContext);

    return (
        <>
            <label>Your name:</label>
            <input type='text' onChange={e => user.setName(e.target.value)} />
            <p>{user.name}</p>
        </>
    )
}
1
Marco 2 oct. 2021 à 20:56

1. Définition de l'état parent pour le contexte dynamique

Premièrement, afin d'avoir un contexte dynamique pouvant être transmis aux consommateurs, je vais utiliser l'état du parent. Cela garantit que j'ai une seule source de vérité à venir. Par exemple, mon application parent ressemblera à ceci:

const App = () => {
  const [name, setName] = useState("John");
  const value = { name, setName };

  return (
   ...
  );
};

Le nom est stocké dans l'état. Nous passerons à la fois name et la fonction setter setName via le contexte plus tard.

2. Créer un contexte

Ensuite, j'ai créé un contexte name comme celui-ci :

// set the defaults
const NameContext = React.createContext({
  name: "John",
  setName: () => {}
});

Ici, je définis les valeurs par défaut pour name ('John') et une fonction setName qui sera envoyée par le fournisseur de contexte au(x) consommateur(s). Ce ne sont que des valeurs par défaut et je fournirai leurs valeurs lors de l'utilisation du composant fournisseur dans l'application parent.

3. Créer un consommateur de contexte

Afin que le sélecteur de nom définisse le nom et s'affiche également, il doit avoir accès à la fonction de définition de nom via le contexte. Cela peut ressembler à ceci :

const NameSwitcher = () => {
const { name, setName } = useContext(NameContext);
 return (
    <label>Your name:</label><br />
    <input type='text' onChange={e => setName(e.target.value)} />
    <p>{name}</p>
  );
};

Ici, je ne fais que définir le nom pour saisir la valeur, mais vous pouvez avoir votre propre logique pour définir le nom pour cela.

4. Envelopper le consommateur dans un fournisseur

Maintenant, je vais rendre mon composant de changement de nom dans un NameContext.Provider et transmettre les valeurs qui doivent être envoyées via le contexte à n'importe quel niveau plus profond. Voici à quoi ressemble mon application parent :

const App = () => {
   const [name, setName] = useState("John");
   const value = { name, setName };

   return (
    <Name.Provider value={value}>
      <NameSwitcher />
    </Name.Provider>
   );
};
2
Tabish Adnan 2 oct. 2021 à 21:00