#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, больше о том, как работают ключи.