Правильный элемент в массиве не всегда удаляется. Контекст реакции

#reactjs

Вопрос:

В моем контексте у меня есть функция удаления, в которую я передаю идентификаторы, чтобы я мог удалять компоненты из массива, однако она не всегда работает правильно. Например, если я добавлю 3 компонента заметок на доску, она всегда удалит последний элемент на доске. Если я добавлю список дел между 2 заметками, они будут удалены правильно. Есть 2 журнала консоли, и удаленный показывает правильный удаленный элемент, а компоненты показывают 2 оставшихся. Опять же, если есть 3 заметки, каждый раз удаляется последний элемент, но если я делаю одну заметку, одну, чтобы сделать, затем еще одну заметку, правильный элемент на доске удаляется.

 import React, { createContext, useReducer, useState } from "react";
import ComponentReducer from "./ComponentReducer";

const NewComponentState: NewComponentsState = {
  components: [],
  addComponent: () => {},
  deleteComponent: () => {},
};

export const NewComponentContext =
  React.createContext<NewComponentsState>(NewComponentState);

export const NewComponentProvider: React.FC = ({ children }) => {
  const [components, setComponents] = useState(NewComponentState.components);

    const deleteComponent = (id: any) => {
      
      for (let i = 0; i < components.length; i  ) {

           if(components[i].id === id) {
             let deleted = components.splice(i, 1)
             console.log(deleted)
             setComponents([...components])
             console.log(components)
           } 
      }
    }
   const addComponent = (newComponent: any) => {
     setComponents([...components, newComponent])
   }
  return (
    <NewComponentContext.Provider
      value={{ components, deleteComponent, addComponent }}
    >
      {children}
    </NewComponentContext.Provider>
  );
};

 

Компонент платы

 import React, { useContext } from "react";
import { NewComponentContext } from "../Context/NewComponentContext";
import NewComponentMenu from "./NewComponents/NewComponentMenu";
import Note from "./NewComponents/Note/Note";
import Photo from "./NewComponents/Photo/Photo";
import TodoList from "./NewComponents/Todo/TodoList";

const newComponents: any = {
  1: TodoList,
  2: Photo,
  3: Note
}
const Board = () => {
    const { components } = useContext(NewComponentContext);

    const componentList  = components.map((component, i) => {
      const id: number = component.componentType
      const NewComponent = newComponents[id]
      
      for (const property in newComponents) {
          const value = parseInt(property)
          if (value == id) {
            return (
              <div key={i}>
                <NewComponent id={component.id}/>
              </div>
            )
          }
      }
    });
  
    return (
      <div className="flex space-x-10 mt-8">
        <NewComponentMenu />
        <div className="grid grid-cols-6 gap-8">{componentList}</div>
      </div>
    );
  };
  
  export default Board;
 

Комментарии:

1. Когда вы видите такое поведение, обычно это не проблема с модификацией массива, а проблема с установкой значимых ключей в отображаемом списке.

2. Хорошо, позвольте мне отредактировать мой пост с помощью компонента доски, на котором отображаются элементы.

3. Ага. Вы используете i в качестве ключа, который является индексом массива. Итак, вы сказали React однозначно идентифицировать экземпляры компонентов по их индексу массива. Поэтому, когда вы удаляете какой- либо элемент из массива, React просто видит, что последний индекс отсутствует (так как все они смещаются вниз), и удаляет этот компонент. Простое исправление: используйте id как key .

4. О, ух ты, спасибо тебе. Так почему же это работает по-другому, когда у меня есть список задач между 2 заметками? Я предполагаю, что это как-то связано с тем, что они разные типы.

5. Трудно сказать, я не думаю, что полностью понимаю другой сценарий. Но вы можете прочитать здесь , в документах React, больше о том, как работают ключи.