Как убедиться, что контекст корректно обновляется для каждого компонента в ReactJS? - PullRequest
1 голос
/ 24 апреля 2020

Я пытаюсь использовать обработчики реакции и контекст для создания приложения планирования. Часть, над которой я сейчас работаю, использует «Создателя задач» для добавления задач в расписание, которое можно предварительно просмотреть над ним в режиме реального времени. Я не могу добавить задачи в предварительный просмотр, когда они добавляются в контекст. Я должен обновить страницу sh для новых задач, чтобы показать в предварительном просмотре. Я перечислю ниже ссылки на код и вещи, которые я пробовал, с которыми я не мог заставить это работать. После того, как я попробовал все эти вещи, есть несколько вещей, которые выделяются для меня, и я чувствую, что это важно, но я не могу понять, как поступить, даже зная их.

- Задачи в локальном хранилище обновляются немедленно когда я добавляю их с помощью создателя задачи

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

- Удаляет задачи в режиме реального времени при предварительном просмотре расписания , страницу не нужно перезагружать

Код, который я считаю наиболее актуальным, - это редуктор, контекст, создатель задачи, предварительный просмотр расписания и основной (родительский элемент как создателя задачи, так и предварительного просмотра расписания) - I думаю, что проблема где-то там


Расписание просмотра

    import React, { useContext, useEffect } from "react";
    import TaskBlock from "../taskblock";
    import ScheduleContextProvider, {
      ScheduleContext,
    } from "../../contexts/ScheduleContext";
    import Task from "../models/taskmodel";

    const SchedulePreview = (props) => {
      const { tasks } = useContext(ScheduleContext);
      console.log(tasks);

      return (
        <React.Fragment>
          <div className="schedulepreviewcontainer">
            <ScheduleContextProvider value={tasks}>
              <div className="schedulepreview">
                {tasks.length
                  ? tasks.map((task) => {
                      return <TaskBlock tID={task.tID} key={task.tID} />;
                    })
                  : null}
              </div>
            </ScheduleContextProvider>
          </div>
        </React.Fragment>
      );
    };

    export default SchedulePreview;

Task Creator


    import React, { useEffect, useContext, useState } from "react";
    import { ScheduleContext } from "../../contexts/ScheduleContext";

    function TaskCreator(props) {
      const { tasks, dispatch } = useContext(ScheduleContext);
      const [taskName, setName] = useState("");
      const [startTime, setStartTime] = useState("");
      const [endTime, setEndTime] = useState("");
      const [taskNotes, setNotes] = useState("");
      const [subtasks, setSubtasks] = useState("");
      const handleSubmit = (e) => {
        e.preventDefault();
        dispatch({
          type: "ADD_TASK",
          task: {
            taskName,
            startTime,
            endTime,
            taskNotes,
            subtasks,
          },
        });
        setName("");
        setStartTime("");
        setEndTime("");
        setNotes("Notes: ");
        setSubtasks([]);
      };

      return (
        <React.Fragment>
          <form onSubmit={handleSubmit}>
            <div id="taskcreator">
              <div className="lineup">
                <div>
                  <input
                    className="tasknameinput taskcreationinput"
                    placeholder="Task Name"
                    type="text"
                    value={taskName}
                    onChange={(e) => setName(e.target.value)}
                    required
                  />
                </div>
                <div>
                  <label htmlFor="starttime"></label>
                  <input
                    className="taskcreationinput timeinput"
                    type="time"
                    name="starttime"
                    onChange={(e) => setStartTime(e.target.value)}
                    value={startTime}
                  />
                  <label htmlFor="endtime"></label>
                  <input
                    className="taskcreationinput timeinput"
                    type="time"
                    name="endtime"
                    onChange={(e) => setEndTime(e.target.value)}
                    value={endTime}
                  />
                </div>
                <div>
                  <div className="create list of subtasks"></div>
                  <div className="creater of subtasks">
                    <input
                      className="subtasknameinput taskcreationinput"
                      placeholder="Subtask Name"
                      type="text"
                    />
                  </div>
                </div>
                <div className="secondpart">
                  <label className="switch" id="typeselector">
                    <input type="checkbox" />
                    <span className="slider"></span>
                  </label>
                  indicator
                </div>
              </div>
              <textarea
                cols="28"
                rows="5"
                className="tasknotesinput taskcreationinput"
                onChange={(e) => setNotes(e.target.value)}
                value={taskNotes}
              ></textarea>
              <div>
                <input type="submit" value="Add" />
              </div>
            </div>
          </form>
        </React.Fragment>
      );
    }

    export default TaskCreator;

Main


    import React, { useContext } from "react";
    import CreationSidebar from "./creationsidebar";
    import SchedulePreview from "./schedulepreview";
    import TaskCreator from "./taskcreator";
    import BackHeader from "../backheader";
    import ScheduleContextProvider, {
      ScheduleContext,
    } from "../../contexts/ScheduleContext";

    function Main() {
      const { tasks, dispatch } = useContext(ScheduleContext);
      return (
        <React.Fragment>
          <div className="doubler">
            <div>
              <CreationSidebar />
            </div>
            <div className="content">
              <ScheduleContextProvider>
                <BackHeader />
                <SchedulePreview props={tasks} />
                <TaskCreator props={tasks} />
              </ScheduleContextProvider>
            </div>
          </div>
        </React.Fragment>
      );
    }

    export default Main;

Ограничитель расписания


    export const scheduleReducer = (state, action) => {
      switch (action.type) {
        case "ADD_TASK":
          return [
            ...state,
            {
              taskName: action.task.taskName,
              tID: Math.random() * 900000,
              pID: 1,
              startTime: action.task.startTime,
              endTime: action.task.endTime,
              isComplete: false,
              taskNotes: action.task.taskNotes,
              subtasks: action.task.subtasks,
            },
          ];
        case "REMOVE_TASK":
          return state.filter((task) => task.tID !== action.tID);
        default:
          return state;
      }
    };

Контекст расписания


        import React, { createContext, useReducer, useEffect } from "react";
        import { scheduleReducer } from "../reducers/schedulereducer";
        import ReactDOM from "react-dom";

        export const ScheduleContext = createContext();

        const ScheduleContextProvider = (props) => {
          const [tasks, dispatch] = useReducer(scheduleReducer, [], () => {
            const localData = localStorage.getItem("tasks");
            return localData ? JSON.parse(localData) : [];
          });
          useEffect(() => {
            localStorage.setItem("tasks", JSON.stringify(tasks));
          }, [tasks]);
          return (
            <ScheduleContext.Provider value={{ tasks, dispatch }}>
              {props.children}
            </ScheduleContext.Provider>
          );
        };

        export default ScheduleContextProvider;


То, что я пробовал, включает повторную визуализацию только предварительного просмотра, когда редуктор вызывается с использованием ловушки эффекта, но это не работает по разным причинам, в зависимости от того, как я пытался это реализовать, вот некоторые из ресурсов, которые я использовал пытаясь это сделать.

https://reactjs.org/docs/thinking-in-react.html https://reactjs.org/docs/rendering-elements.html https://reactjs.org/docs/hooks-effect.html https://reactjs.org/docs/conditional-rendering.html https://reactjs.org/docs/state-and-lifecycle.html

Я попытался удалить реквизиты из всего, для чего вместо этого можно использовать состояние, а также передать реквизиты в основном всему, в надежде, что в какой-то момент они изменятся, и компонент будет перерисован с новое состояние. Я получил эти идеи от Почему мой компонент реагирования не обновляется с обновлениями состояния?

После этого я начал пробовать случайные вещи, потому что не мог понять это.

Я попытался изменить ScheduleContextProvider на ScheduleContext.Provider, который ничего не делал (без ошибок или чего-то такого, что никогда не загрузится) Я также попытался добавить ScheduleContext.Consumer мест, но это тоже не сработало.

У меня есть также попытался просто вызвать функцию редуктора по умолчанию, чтобы попытаться «обновить» 1079 * состояние при создании задачи

Недавно я узнал о хуках, контексте и редукторах из учебника на Youtube, код из которого я был в состоянии прекрасно работать до использования здесь хуков. Я провел много времени, сравнивая свой код с кодом учебника (https://github.com/iamshaunjp/react-context-hooks), но не могу понять, почему он работает там, но не в этом приложении.

Я не знаю, если это полезно, но полный код находится на GitHub здесь https://github.com/asmenezes/scheduledaily

И у меня есть текущий (в версии Progress) на страницах GitHub Здесь - https://asmenezes.github.io/scheduledaily/

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация

1 Ответ

0 голосов
/ 09 мая 2020

Не знаю почему, но изменив предварительный просмотр расписания на

import React, { useContext } from "react";
import TaskBlock from "../taskblock";
import { ScheduleContext } from "../../contexts/schedulecontext";

const SchedulePreview = () => {
  const { tasks } = useContext(ScheduleContext);
  console.log(tasks);

  return (
    <div className="schedulepreviewcontainer">
      <div className="schedulepreview">
        <ul>
          {tasks.map((task) => {
            return <TaskBlock task={task} key={task.tID} />;
          })}
        </ul>
      </div>
    </div>
  );
};

export default SchedulePreview;

Исправлено, в основном просто помещая элементы блока задач в UL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...