React - Rerender при изменении props / динамическом изменении css без rerender - PullRequest
0 голосов
/ 06 августа 2020

У меня есть требование скрыть содержимое страницы в приложении React, когда навигация отображается / скрыта.

Для этого мы передаем опору компоненту и обрабатываем отображение css в стилизованных компонентах вот так:

<PageContent isOpen={isOpen}>
const PageContent = styled.div`
  display: ${props => (props.isOpen ? 'none' : 'block')};
`;

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

В этом случае содержимое страницы включает некоторый контент, который извлекается из API, и поэтому каждый раз, когда открывается / закрывается навигация, мы снова визуализируем контент и снова извлекаем из API, что не требуется.

Есть ли способ динамически контролировать скрытие / отображение основного держателя контента без каждого повторного рендеринга? Или нам следует больше изучить компонент, который выполняет выборку, а не обновляет ее?

Ответы [ 4 ]

0 голосов
/ 07 августа 2020

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

здесь пример получения данных компонента при монтировании и кнопка, которая запускает состояние на click: код

import React, { useState, useEffect } from "react";
import "./styles.css";
import MyData from "./MyData";

const fakePromise = () =>
  new Promise((resolve) => {
    setTimeout(() => {
      resolve("data returned");
    }, 2000);
  });
export default function App() {
  const [hidden, setHidden] = useState(false);
  const [data, setData] = useState();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data = await fakePromise();
        setData(data);
      } catch (error) {
        throw error;
      }
    };
    fetchData();
  }, []);
  return (
    <div className="App">
      <div style={{ display: hidden ? "none" : "block" }}>I am visible</div>
      <button onClick={() => setHidden(!hidden)}>Toggle Visiblity</button>
      {data && <MyData data={data} />}
    </div>
  );
}

в примере, как вы можете видеть, компонент MyData не передает скрытое состояние, но он будет повторно визуализироваться, если мы не заключим его в React.memo.

MyData. js

import React from "react";

const MyData = ({ data }) => {
  console.log("render");
  return (
    <div>
      <h1>{data}</h1>
    </div>
  );
};

//export default MyData;

export default React.memo(MyData);

примечание: React.memo сравните текущие реквизиты и следующие реквизиты, и если некоторые из этих реквизитов являются функцией или c данными array/object каждый раз при повторном рендеринге компонента они будут воссоздан, который будет повторно отображать ребенка, поэтому вам нужно запомнить эти реквизиты с помощью таких крючков, как useCallback или useMemo.

спасибо, надеюсь, это ответит на ваш вопрос.

0 голосов
/ 06 августа 2020

В точности это ожидаемое поведение. Вы можете не использовать CSS, чтобы скрыть компонент, а скорее возвращать пустой фрагмент, если isOpen истинно, предотвращая вызовы API, если эти вызовы исходят из внутреннего компонент

 <>
 </>

если возможно

0 голосов
/ 07 августа 2020

Я закончил тем, что обернул основной контент, который не заботился о родительской опоре, в PureComponent.

React's PureComponent выполняет поверхностное сравнение свойств и состояния компонента. Если ничего не изменилось, это предотвращает повторную визуализацию компонента. Если что-то изменилось, компонент повторно визуализируется.

0 голосов
/ 06 августа 2020

Изменение компонента css на отображение скрытого должно скрывать его только визуально, но компоненты все равно должны быть смонтированы в дереве DOM. при установке компонентов.

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