Здравствуйте! Прошу прощения за беспокойство, но я столкнулся с проблемой в своём проекте. Я — начинающий разработчик, и мне нужно немного помощи. У меня есть недоделанный проект, который можно найти по ссылке <a href="https://github.com/m3tmrphss/example" rel="nofollow">https://github.com/m3tmrphss/example</a>. В структуре проекта в папке `src/components/main/main-components` есть две папки: `backlog` и `ready`, каждая из которых содержит по одному компоненту React. Я уже настроил два взаимодействующих списка, где в `backlog` я добавляю задачи, а затем могу перемещать их в `ready`. Проблема в том, что задача из `backlog` не удаляется автоматически при перемещении её в `ready` — она удаляется только после нажатия кнопки "Добавить задачу". Я попробовал множество решений, использовал `useContext`, но не достиг желаемого результата. Ранее также пытался обновлять массив через `useEffect`, но это не сработало. Буду очень признателен за любую помощь или совет по решению этой проблемы!
Здравствуйте!
Ваша проблема связана с тем, как вы управляете состоянием ваших компонентов в React. Чтобы удалить задачу из одного списка (например, `backlog`) при её перемещении в другой список (например, `ready`), нужно правильно обновить состояние, которое хранит ваши задачи.
Предположим, у вас есть массив задач в компоненте `backlog`, и вы хотите удалить задачу из этого массива, когда она перемещается в `ready`. Вот пошаговая инструкция, как это сделать:
1. **Убедитесь, что вы управляете состоянием для обеих списков.** Это может быть сделано в родительском компоненте, который будет хранить и передавать задачи в компоненты `backlog` и `ready`.
2. **Создайте функции для удаления задач из `backlog`.** Эта функция будет принимать идентификатор задачи и удалять её из состояния.
3. **При перемещении задачи из `backlog` в `ready` вызывайте эту функцию удаления.** Таким образом, задача будет удалена из массива `backlog`, и компонент снова перерисуется.
Вот примерный код, который иллюстрирует этот подход:
```jsx
import React, { useState } from 'react';
import Backlog from './backlog/Backlog';
import Ready from './ready/Ready';
const App = () => {
// Состояния для задач
const [backlogTasks, setBacklogTasks] = useState([{ id: 1, text: 'Task 1' }, { id: 2, text: 'Task 2' }]);
const [readyTasks, setReadyTasks] = useState([]);
// Функция для перемещения задачи в готовую
const moveToReady = (taskId) => {
const taskToMove = backlogTasks.find(task => task.id === taskId);
if (taskToMove) {
// Удаляем задачу из backlog
setBacklogTasks(backlogTasks.filter(task => task.id !== taskId));
// Добавляем задачу в ready
setReadyTasks([...readyTasks, taskToMove]);
}
};
return (
<div>
<h1>Backlog</h1>
<Backlog tasks={backlogTasks} onMoveToReady={moveToReady} />
<h1>Ready</h1>
<Ready tasks={readyTasks} />
</div>
);
};
export default App;
```
В компоненте `Backlog`, вы могли бы использовать `onMoveToReady` вот так:
```jsx
const Backlog = ({ tasks, onMoveToReady }) => {
return (
<ul>
{tasks.map(task => (
<li key={task.id}>
{task.text}
<button onClick={() => onMoveToReady(task.id)}>Move to Ready</button>
</li>
))}
</ul>
);
};
```
В этом примере, когда вы нажимаете кнопку "Move to Ready", вызывается функция `moveToReady`, которая удаляет задачу из `backlogTasks` и добавляет её в `readyTasks`. Это вызывает перерисовку компонентов, и задача исчезает из списка `backlog`.
Убедитесь, что ваше состояние правильно обновляется в соответствии с этим подходом. Если у вас появятся дополнительные вопросы или вы столкнётесь с конкретными проблемами в коде, не стесняйтесь делиться ими! Удачи в разработке!
1. Зачем вам нужен тут Context? Добавьте useState со списком задач в main компонент и передавайте их в дочерние компоненты:
export function MainNode() { const [tasks, setTasks] = useState(predefinedTasks) const addTask = (listName, task) => { // .. // setTasks // .. } const removeTask = (listNaem, taskId) => { // ... // setTasks // .. } const moveTask = (fromListName, toListName, taskId) => { // .. // setTasks // .. } return ( <main> <BacklogTasksContainer tasks={tasks.backlog} addTask={addTask}/> <ReadyTasksContainer ... /> <InProgressTasksContainer ... /> <FinishedTasksContainer ... /> </main> ) }
2. Если вам необходимо по каким-то причинам использовать context, то по аналогии с примером выше:
export const TaskContext = createContext(); export const TaskProvider = ({ children }) => { const [tasks, setTasks] = useState(predefinedTasks) const addTask = (listName, task) => { // .. // setTasks // .. } const removeTask = (listNaem, taskId) => { // ... // setTasks // .. } const moveTask = (fromListName, toListName, taskId) => { // .. // setTasks // .. } return ( <TaskContext.Provider value={{ tasks, moveTask, addTask }}> {children} </TaskContext.Provider> ); }
После чего используйте:
const TaskList = ({ listName }) => { const { tasks, moveTask, addTask } = useContext(TaskContext); // .... }
Вам надо почитать как работает реактивность в React и разобраться почему изменения в объекте не триггерят рирендер компонента. Если по простому, то Вам нужно не просто добавлять (push) новый task в список, а полностью заменять весь объект (data) с тасками и не использовать для каждого компонента свой useState
// так не работет tasks.backlog.push(...) // так работает setTasks(currentState => { currentState.backlog.push(...) return currentState })