Predaytor
@Predaytor
C# .NET Core, React, Typescript

Как использовать и обновлять данные с контекста в разных компонентах?

Данные (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>
  );
}
  • Вопрос задан
  • 143 просмотра
Решения вопроса 1
Predaytor
@Predaytor Автор вопроса
C# .NET Core, React, Typescript
Насколько я понимаю React гарантирует что dispatch будет обновляться только при изменении своего type action. Поэтому зависимость dispatch в useEffect не вызывает ререндера.
Для хранения переменной из контекста в компоненте, сделал так: const { lists } = state;
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы