Данные (lists) используются в Lists, их нужно обновлять в другом компоненте при событии. Возникает ряд проблем:
Что бы сфетчить теперь нужно добавить dispatch редюсера в список зависимостей useEffect, как избавится от ререндера, но записать данные в контекст?
Как использовать данные отдельно от обьекта state? Несколько раз писать state.lists излишне.
Есть метод setWrapped, он использует те же данные, теперь я могу переместить его в дочерний List без передачи пропов, раз я имею доступ к контексту вместо локального useState?
Lists:
import React, { useEffect, useContext } from "react";
import { getAllLists, getAllNotes } from '../api';
import { StoreContext } from '../store';
import { List } from "./List";
export const Lists = () => {
const { state, dispatch } = useContext(StoreContext);
useEffect(() => {
const fetchLists = async () => {
const data = await getAllLists();
dispatch({ type: 'SET_LISTS', payload: data });
};
fetchLists();
}, [dispatch]);
const setWrapped = id => {
const data = [...state.lists];
const idx = data.findIndex(i => i.id === id);
data[idx].wrapped = !data[idx].wrapped;
dispatch({ type: 'SET_LISTS', payload: data });
};
return (
<section className="lists">
<>
{state.lists.map(list => (
<List key={list.id} list={list} setWrapped={setWrapped}>{...}</List>
))}
</>
</section>
);
}
ActionSidebar, который должен обновить состояние (при клике изменять свойство wrapped на true и обратно). Свойство wrapped хранится в базе и может быть разным у каждого List.
import React, { useContext } from 'react';
import { StoreContext } from '../store';
export const ActionSidebar = () => {
const { state, dispatch } = useContext(StoreContext);
const wrapListsHandler = () => {
dispatch({type: 'SET_WRAP_ALL_LISTS', payload: !state.wrapAllLists});
let data = [...state.lists];
if (state.wrapAllLists) {
data = data.map(i => {
return {
...i,
wrapped: false
}
});
}
else {
data = data.map(i => {
return {
...i,
wrapped: true
}
});
}
dispatch({type: 'SET_LISTS', payload: data});
};
return (
<aside className="action-sidebar">
<button onClick={wrapListsHandler} />
</aside>
);
}