1
votes

useState sur React Hooks ne mettant pas à jour Array

J'ai essayé beaucoup de choses et je n'arrive pas à comprendre pourquoi setTypes ne met pas à jour le tableau 'types' ??

import { useState, useEffect } from 'react';
import { PostList } from './post-list';
import * as api from '../utils/api';

export const PostSelector = (props) => {
  const [posts, setPosts]     = useState([]);
  const [loading, setLoading] = useState(false);
  const [type, setType]       = useState('post');
  const [types, setTypes]     = useState([]);
  
  const fetchTypes = async () => {
    setLoading(true);
    const response = await api.getPostTypes();
    delete response.data.attachment;
    delete response.data.wp_block;
    const postTypes = response.data;
    console.log(response.data); // {post: {…}, page: {…}, case: {…}}
    setTypes(postTypes);
    console.log(types); // []

    // Why types remain empty??
  }

const loadPosts = async (args = {}) => {
  const defaultArgs = { per_page: 10, type };
  const requestArgs = { ...defaultArgs, ...args };
  

  requestArgs.restBase = types[requestArgs.type].rest_base; // Cannot read property 'rest_base' of undefined
  
  const response = await api.getPosts(requestArgs);
  console.log(response.data);
}

useEffect(() => {
  fetchTypes();
  loadPosts();
}, []);

  return (
    <div className="filter">
      <label htmlFor="options">Post Type: </label>
      <select name="options" id="options">
        { types.length < 1 ? (<option value="">loading</option>) : Object.keys(types).map((key, index) => <option key={ index } value={ key }>{ types[key].name }</option> ) }
      </select>
    </div>
  );
}

S'il vous plaît, jetez un œil à console.log et notez les différentes réponses.

Ce que j'essaie de faire est de charger la liste des types, dans ce cas 'post', 'page' et 'case', puis d'afficher une liste de posts en fonction de l'actuel 'taper'. Le type par défaut est 'post'.

Si j'ajoute [types] à useEffect. J'ai enfin obtenu les valeurs mais le composant est rendu sans interruption.

Merci à tous pour vos commentaires. Plusieurs personnes ont souligné le problème, étant que, le fait que nous définissions l'état ne signifie pas qu'il sera défini tout de suite parce qu'il est asynchrone.

Comment pouvons-nous résoudre ce problème alors? Quelles que soient les raisons, comment y parvenir? Comment pouvons-nous travailler avec notre état à tout moment et effectuer des calculs basés sur notre état si nous ne savons pas quand il sera disponible? Comment pouvons-nous nous assurer que nous attendons tout ce dont nous avons besoin, puis utilisons les valeurs que nous attendons?


14 commentaires

Essayez d'utiliser l'opérateur de propagation. setTypes ([... postTypes]);


Merci pour la réponse rapide, mais cela renvoie les mêmes résultats.


ressemble à response.data est un objet, pas un tableau


Je ne sais pas si setTypes () est une méthode asynchrone. Mais essayez d'utiliser await, await setTypes ([... postTypes]);


Vous ne recevez aucune erreur sur console.log ? Cela s'ajouterait également à la question pour les publier, si vous en recevez.


Merci @GlenK. J'ai essayé d'ajouter un objet comme valeur par défaut des types, juste pour voir si cela mettrait à jour l'état, ne fonctionnera toujours pas. Renvoie un objet vide au lieu d'un tableau vide.


Merci @AlexanderSantos. Mais pas d'erreurs.


Merci @boosted_duck essayé avec await, mais avec et sans l'opérateur de propagation, toujours le même résultat exact.


Est-ce que cela répond à votre question? Méthode de définition de useState ne reflétant pas immédiatement le changement


Cela répond à votre question. stackoverflow.com/questions/60294328/...


Merci @ZainUlAbideen! Le problème dans ce cas est que types est un objet, de sorte que useEffect est renvoyé pour toujours.


Votre bienvenue, mais je ne comprends pas que la façon dont le re-rendu est connecté aux types étant des objets?


@ZainUlAbideen jetez un œil à ceci: dev.to/ karthick3018 /…


@drjorgepolanco, Merci, j'espère que vous avez lu les commentaires de cet article;) Heureux que cela vous ait aidé. Bon codage.


3 Réponses :


0
votes

Il semble que useState est asynchrone et ne met pas à jour la valeur instantanément après l'avoir appelée.

Consultez ce même cas ici


0 commentaires

0
votes

La fonction setTypes de

useState est une fonction asynchrone donc les modifications ne prennent pas effet immédiatement. Vous pouvez utiliser useEffect pour vérifier si quelque chose change

useEffect(()=>{
    const defaultArgs = { per_page: 10, type };
    const requestArgs = { ...defaultArgs, ...args };
    requestArgs.restBase = types;
    console.log("types updated",types)
},[types])

Vous pouvez supprimer loadPosts car maintenant useEffect fonctionnera chaque fois que les types changent


2 commentaires

Si je passe [types], le rendu ne s'arrête jamais.


C'est étrange. Pouvez-vous fournir un exemple de code sur stackblitz.com/edit/react-leukwv afin que je puisse tester il.



0
votes

Vous avez déclaré que vos types sont un tableau, mais vous lui passez un dictionnaire de dictionnaires. Essayez ceci:

loadPosts()

Vous n'avez pas non plus besoin d'appeler

const [types, setTypes]     = useState({});

car le hook useState rendra votre composant, ne mettant à jour que ce est nécessaire.


0 commentaires