繁体   English   中英

React - 重新渲染道具更改/动态更改 css 而无需重新渲染

[英]React - Rerender on props change / dynamically changing css without rerender

我需要在显示/隐藏导航时隐藏 React 应用程序上的页面内容。

为此,我们将 prop 传递给组件,并在样式组件中处理显示 css,如下所示:

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

虽然这可以正常工作,但当道具更改时,内部页面内容会重新呈现,这是预期但不希望的。

在这种情况下,页面内容包括从 API 获取的一些内容,因此每次打开/关闭导航时,我们都会再次呈现内容并再次从 API 获取,这是不需要的。

有没有办法动态控制隐藏/显示主要内容持有者,而无需每次都重新渲染? 还是我们应该更多地研究执行获取而不是更新的组件?

将组件 css 更改为显示隐藏应该只会在视觉上隐藏它,但组件仍应安装在 DOM 树上。

也许您的 API 提取在每次重新渲染时都会发生,而应该只在组件安装时发生。

正是这是一个预期的行为,你可以做的不是使用 CSS 隐藏组件,而是返回并清空片段,如果“isOpen”为真,防止 API 调用,如果这些调用来自内部组件

 <>
 </>

如果可能的话

我最终将不关心父道具的主要内容包装在PureComponent中。

React 的 PureComponent 对组件的 props 和 state 进行了浅层比较。 如果没有任何改变,它会阻止组件的重新呈现。 如果发生了变化,它会重新渲染组件。

每当一个组件触发 state 时,它的所有子组件都会重新渲染,即使子组件没有中继该 state。 要解决此问题,您需要使用React.memo为功能组件包装子组件,或为 class 组件使用PureComponent 这将检查道具更改并重新渲染孩子。

这里有一个组件在安装时获取数据的示例,并且有一个按钮,在click时触发 state: 代码

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组件不会在隐藏的 state 上中继,但如果我们没有将其包装在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比较当前道具和下一个道具,如果其中一些道具是 function 或 static 数据array/object ,每次组件重新渲染时,这些将被重新创建,这将重新渲染孩子,所以你需要记住这些道具使用诸如useCallbackuseMemo类的钩子。

谢谢希望这能回答你的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM