Пытаетесь визуализировать функциональный компонент после ajax запроса? - PullRequest
0 голосов
/ 11 апреля 2020

ОБНОВЛЕНИЕ : ошибка произошла из-за [project, setProject] = useState(null);, вместо этого должно быть const [project, setProject] = useState({}); Невозможно инициализировать состояние с ошибкой бросков NULL ... Я думал, что сработает рендер <p> loading </p>. .. что я не знаю, почему не запускается.

Я хочу отобразить свой компонент, как только ajax запросов успешно захватят данные, т.е. project object. Я использую useLayoutEffect для синхронного выполнения этого ajax запроса.

Однако я получаю

TypeError: Невозможно прочитать свойство 'tasksNumber' из undefined

Как сначала получить данные, а затем отобразить компонент?

function EditProjectView(props) {
  const [project, setProject] = useState(null);

  // get id from params
  const id = useParams();

  // after renders it will use this hook
  useLayoutEffect(() => {
    // fake* ajax request to database
    const data = database.projects.find((project) => {
      return project.id == id;
    }, []);

    setProject(data);

    console.log("Let's see:", project);
  });

  const projectView = (
    <React.Fragment>
      <main style={classes.content}>
        <div style={classes.projectContainer}>
          <div style={classes.projectOverviewWrapper}>
            <Paper elevation={2}>
              <div style={classes.project}>
                {<ProjectDetailsView project={project} />}
              </div>
            </Paper>
          </div>
          <div style={classes.tasksContainer}>
            <h3>
              ALL TASKS
              {project.tasksNumber} <---------------- here?
            </h3>
            <TaskExpansionPanel
              panelTitle={<PanelTitle />}
              panelDetails={<PanelDescription />}
            />
            <CreateTaskBtn />
          </div>
        </div>
      </main>
      }
    </React.Fragment>
  );

  return project !== null ? (
    <LayoutGrid view={projectView} />
  ) : (
    <p>loading...</p>
  );
}

export default EditProjectView;

база данных. js

var database = {
  projects: [
    {
      id: 1,
      projectName: "Write a book",
      tasksNumber: 15,
      startDuration: new Date().toDateString(),
      endDate: new Date().toDateString(),
      projectCreator: "joe",
    },
    {
      id: 2,
      projectName: "Code an app",
      tasksNumber: 4,
      startDuration: new Date().toDateString(),
      endDate: new Date().toDateString(),
      projectCreator: "Samir",
    },
    {
      id: 3,
      projectName: "Finish Assignment",
      tasksNumber: 12,
      startDuration: new Date().toDateString(),
      endDate: new Date().toDateString(),
      projectCreator: "Potter",
    },
  ],
};

module.exports = database;

1 Ответ

0 голосов
/ 11 апреля 2020

Имейте в виду, что эффекты запускаются после рендеринга компонента, поэтому при первом рендеринге состояние имеет значение null.

update

В вашем случае использование useLayoutEffect означает необязательно, вы можете заменить его на useEffect.

. useEffect вызывается с помощью следующей последовательности: React отображает ваш компонент> Paint браузера> useEffect ()

useLayoutEffect, вместо этого вызывается так: React визуализирует ваш компонент> useLayoutEffect ()> краска для браузера

<h3>
     ALL TASKS
     {project ? project.tasksNumber : "Loading..."}
</h3>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...