387 votes

Méthode Push dans React Hooks (useState) ?

Comment pousser un élément dans le React hook du tableau useState ? Est-ce une ancienne méthode dans react state ? Ou quelque chose de nouveau ?

Par exemple exemple de setState push ?

808voto

T.J. Crowder Points 285826

Lorsque vous utilisez useState vous pouvez obtenir une méthode de mise à jour pour l'élément d'état :

const [theArray, setTheArray] = useState(initialArray);

ensuite, lorsque vous voulez ajouter un nouvel élément, vous utilisez cette fonction et passez le nouveau tableau ou une fonction qui créera le nouveau tableau. Normalement, c'est cette dernière qui est utilisée, puisque les mises à jour d'état sont asynchrones et parfois groupées :

setTheArray(oldArray => [...oldArray, newElement]);

Parfois, vous pouvez vous en sortir sans utiliser ce formulaire de rappel, si vous uniquement mettre à jour le tableau dans les gestionnaires pour certains événements spécifiques de l'utilisateur comme click (mais pas comme mousemove ) :

setTheArray([...theArray, newElement]);

Les événements pour lesquels React s'assure que le rendu est purgé sont les "événements discrets" énumérés. aquí .

Exemple en direct (passage d'un callback dans setTheArray ) :

const {useState, useCallback} = React;
function Example() {
    const [theArray, setTheArray] = useState([]);
    const addEntryClick = () => {
        setTheArray(oldArray => [...oldArray, `Entry ${oldArray.length}`]);
    };
    return [
        <input type="button" onClick={addEntryClick} value="Add" />,
        <div>{theArray.map(entry =>
          <div>{entry}</div>
        )}
        </div>
    ];
}

ReactDOM.render(
    <Example />,
    document.getElementById("root")
);

<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>

Parce que la seule mise à jour de theArray là-dedans, il y a celui dans un click (l'un des événements "discrets"), je pourrais m'en sortir avec une mise à jour directe dans le fichier addEntry :

const {useState, useCallback} = React;
function Example() {
    const [theArray, setTheArray] = useState([]);
    const addEntryClick = () => {
        setTheArray([...theArray, `Entry ${theArray.length}`]);
    };
    return [
        <input type="button" onClick={addEntryClick} value="Add" />,
        <div>{theArray.map(entry =>
          <div>{entry}</div>
        )}
        </div>
    ];
}

ReactDOM.render(
    <Example />,
    document.getElementById("root")
);

<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>

3 votes

...et essayez setTheArray(currentArray => [...currentArray, newElement]) si ce qui précède ne fonctionne pas. Très probablement dans useEffect(...theArray..., []) il est important de comprendre que theArray est une constante, donc les mises à jour fonctionnelles sont nécessaires pour les valeurs des futurs rendus

1 votes

@Aprillion - Je ne suis pas sûr de ce que vous voulez dire par là. useEffect exemple... ?

1 votes

Si le useEffect a une liste de dépendances vide [] il ne sera exécuté que lors du premier rendu. Ainsi, la valeur de theArray à l'intérieur, l'effet sera toujours initialArray . Dans les situations où setTheArray([...initialArray, newElement]) n'aurait pas de sens, et lorsque theArray sera toujours égale à initialValue alors des mises à jour fonctionnelles sont nécessaires.

129voto

Elia Ahadi Points 57

Pour aller un peu plus loin, voici quelques exemples courants. En commençant par :

const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);

Pousser l'élément à la fin du tableau

setTheArray(prevArray => [...prevArray, newValue])

Push/update élément à la fin de l'objet

setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));

Pousser/mettre à jour l'élément à la fin du tableau d'objets

setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);

Pousser l'élément à la fin de l'objet des tableaux

let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);

Voici également quelques exemples concrets. https://codesandbox.io/s/reacthooks-push-r991u

5 votes

Merci pour tous ces exemples. La chose exacte avec laquelle j'ai eu un problème était ton Pousser l'élément à la fin de l'objet des tableaux . J'ai essayé tant de choses différentes, mais je n'ai pas réussi à me débrouiller.

1 votes

L'utilisation de prevState a résolu mon problème, à savoir que seul le dernier appel était appliqué sur un concat et un filtre de tableau simultanés.

30voto

Mohammad Fallah Points 316

Vous pouvez ajouter un tableau de données à la fin de l'état personnalisé :

  const [vehicleData, setVehicleData] = React.useState<any[]>([]);
  setVehicleData(old => [...old, ...newArrayData]);

Par exemple, dans le tableau ci-dessous, vous voyez un exemple d'axios :

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios(
        {
          url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
          method: 'get',
        }
      );
      setVehicleData(old => [...old, ...result.data.data]);
    };

    fetchData();
  }, [page]);

17voto

La méthode la plus recommandée est l'utilisation conjointe de la fonction wrapper et de l'opérateur d'étalement. Par exemple, si vous avez initialisé un état appelé name comme ça,

const [names, setNames] = useState([])

Vous pouvez pousser vers ce tableau comme ceci,

setNames(names => [...names, newName])

J'espère que cela vous aidera.

1 votes

Veuillez ne pas publier de réponses uniquement sous forme de liens. Le lien pourrait être rompu à l'avenir. Créez plutôt un compte rendu de cet article et assurez-vous de répondre réellement à la question.

0 votes

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses ne comportant qu'un lien peuvent devenir invalides si la page liée change. - De la revue

7voto

Adarsh Pawar Points 428
// Save search term state to React Hooks with spread operator and wrapper function

// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))

// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))

// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])

// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])

https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X