каждый раз, когда состояние триггера компонента изменяется, все его дочерние элементы будут повторно отображаться, даже если дочерний элемент не передает это состояние. Чтобы решить эту проблему, вам необходимо обернуть дочерний компонент с помощью 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
.
спасибо, надеюсь, это ответит на ваш вопрос.