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

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

为此,我们将一个 prop 传递给组件,并像这样处理样式化组件中的显示 css:

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

虽然这工作正常,但当 prop 更改时,内页内容会重新呈现,这是预期的但不是期望的。

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

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


DIEA
浏览 183回答 4
4回答

郎朗坤

将组件 css 更改为显示隐藏应该只会在视觉上隐藏它,但组件仍应挂载在 DOM 树上。也许你的 API 获取是在每次重新渲染时发生的,而它应该只在组件安装时发生。

至尊宝的传说

这正是预期的行为,您可以做的不是使用 CSS 隐藏组件,而是返回并清空 Fragment,如果“isOpen”为真,则阻止 API 调用,如果这些调用来自内部组件&nbsp;<> &nbsp;</>如果可能的话

12345678_0001

我最终将不关心 parent 道具的主要内容包装在PureComponent.React 的 PureComponent 对组件的 props 和 state 进行了浅层比较。如果什么都没有改变,它会阻止组件的重新渲染。如果发生了变化,它会重新渲染组件。

三国纷争

每次组件触发状态更改时,即使子组件不依赖于该状态,它的子组件也会重新渲染。要解决此问题,您需要将子组件包装React.memo为功能组件或PureComponent用于类组件。这将检查道具变化并重新渲染孩子。这里有一个组件在挂载上获取数据的示例,并有一个触发状态的按钮click:代码import React, { useState, useEffect } from "react";import "./styles.css";import MyData from "./MyData";const fakePromise = () =>&nbsp; new Promise((resolve) => {&nbsp; &nbsp; setTimeout(() => {&nbsp; &nbsp; &nbsp; resolve("data returned");&nbsp; &nbsp; }, 2000);&nbsp; });export default function App() {&nbsp; const [hidden, setHidden] = useState(false);&nbsp; const [data, setData] = useState();&nbsp; useEffect(() => {&nbsp; &nbsp; const fetchData = async () => {&nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; const data = await fakePromise();&nbsp; &nbsp; &nbsp; &nbsp; setData(data);&nbsp; &nbsp; &nbsp; } catch (error) {&nbsp; &nbsp; &nbsp; &nbsp; throw error;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };&nbsp; &nbsp; fetchData();&nbsp; }, []);&nbsp; return (&nbsp; &nbsp; <div className="App">&nbsp; &nbsp; &nbsp; <div style={{ display: hidden ? "none" : "block" }}>I am visible</div>&nbsp; &nbsp; &nbsp; <button onClick={() => setHidden(!hidden)}>Toggle Visiblity</button>&nbsp; &nbsp; &nbsp; {data && <MyData data={data} />}&nbsp; &nbsp; </div>&nbsp; );}在示例中,您可以看到MyData组件不依赖隐藏状态,但如果我们不将其包装在React.memo.我的数据.jsimport React from "react";const MyData = ({ data }) => {&nbsp; console.log("render");&nbsp; return (&nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; <h1>{data}</h1>&nbsp; &nbsp; </div>&nbsp; );};//export default MyData;export default React.memo(MyData);注意:React.memo比较当前道具和下一个道具,如果其中一些道具是函数或静态数据,则array/object每次组件重新渲染时将重新创建这些道具,这将重新渲染孩子,因此您需要使用useCallback或之类的钩子来记住这些道具useMemo。谢谢希望这能回答你的问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript