J'ai une configuration de tableaux de champs imbriqués, utilisez react-hook-form ici. Notez que mon code actuel est un peu plus complexe, mais le problème est affiché ici de la même manière.

enter image description here

Le problème que j'ai est que si je supprime un élément de la liste, disons ID: 2 dans la liste [{ID:1}, {ID:2}, {ID:3}], le résultat n'est pas [{ID:1}, {ID:3}], mais [{ID:1}, {ID:2}].

Voici le exemple officiel, qui obtient le bon tableau de champs imbriqués.

Pour autant que je sache, la seule différence est que mon formulaire repose sur des données récupérées à partir d'une API (dans mon exemple, gérées par une fonction async) alors que l'exemple officiel utilise des données déjà initiées.

En regardant des exemples en ligne, certains utilisent le champ <Controller>, mais cela m'a donné plus de problèmes (dans mon code réel), et lors des tests (dans Code Sandbox), ne change pas vraiment le fait que la suppression de 2 ne déplace pas l'ensemble du tableau vers le haut.

Y a-t-il quelque chose qui me manque?

3
zack_falcon 7 oct. 2020 à 16:11

1 réponse

Meilleure réponse

Vous ne devez pas transmettre l'index de tableau en tant que key à chaque enfant dans une liste d'enfants. Voici le code problématique :

{fields.map((task, j) => {
  return (
    <Box key={j} padding={2} border={1}>
      {...}
    </Box>
  );
})}

Lorsque vous exécutez le code ci-dessus, vous aurez des enfants avec le tableau de données correspondant comme celui-ci

{ key: 0, task: { id: "1", freq: "d" },
{ key: 1, task: { id: "2", freq: "d" },
{ key: 2, task: { id: "3", freq: "d" },

Si vous supprimez le premier élément, dans le prochain rendu, le tableau de données ressemblera à ceci

{ key: 0, task: { id: "2", freq: "d" },
{ key: 1, task: { id: "3", freq: "d" },

C'est parce que le premier élément où task.id = 1 a été supprimé, mais l'index du tableau commence toujours à partir de 0, donc à la fin il y a une incompatibilité entre key et task.id .

Le meilleur moyen de résoudre ce problème consiste à utiliser un identifiant unique directement à partir de votre modèle au lieu de l'index de tableau en tant que key :

{fields.map((task, j) => {
  return (
    <Box key={task.id} padding={2} border={1}>
      {...}
    </Box>
  );
})}

Démo en direct

Edit 64244731/react-hook-form-nested-fieldarray-deleting-item-in-the-middle-of-the-list-does

4
NearHuscarl 8 oct. 2020 à 04:22