当 props 为空时停止重新渲染

问题描述 投票:0回答:1

我有一个组件可以呈现一些错误/警告

function getErrorOption(errorType: string): string {
    switch (errorType) {
      case 'error_zero':
        return `zero_error`;
      case 'Error_Option_1':
        return `Some String Value`;
      case 'Error_Option_2':
        return `some string value`;
      default:
        return '';
    }
  }

export default component myComponent(...props: Props) {
  const {name, ID} = props;
  const [errorType, setErrorType] = useState('');

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(`YOUR_API_ENDPOINT/${id}`);
        const data = response.data;
        setData(data);
        if (data.generic_dataset_exists === false) {
            // don't render anything
        } else if (data.inactive_data_upload === true) {
          // don't render anything
        } else if (
          data.total_active_items / data.total_items <
           0.5 // it can be anything.
        ) {
          setErrorType('Error_Option_1');
        } else if (
          data.total_empty_items /
            data.total_active_items >
            0.2 // doesn't matter what this is 
        ) {
            setErrorType('Error_option_2')
        }
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };
    fetchData();
  }, [id]);

  const  final_error= getErrorOption(errorType);

  return final_error ? (
<SOMETINGRENDERING errortype = {final_error}> </SOMETINGRENDERING>
  ) : null;
}

使用 my_id 从父组件调用该组件

const my_id = // id comes from some state mgmt, this state is 
changed from multiple component , this is readonly access. 
{
my_id ? <MyComponent id = {my_id}/>
}

首次调用时会使用正确的 id 来调用该组件,以后调用时可以为 null/空字符串 ''。 我的 api 获取是正确的,不需要修复,我需要修复的只是它的渲染和重新渲染以及删除警告组件的方式。

我的要求

  1. 当第一次使用正确的 ID(非空/非空/未定义)调用组件时,显示错误/警告
  2. 当第二次出现不同的正确ID时,更改ID并获取数据并重新渲染警告
  3. 当使用空/未定义/空属性调用组件时(这种情况仅在正确的 ID 之后调用组件),这会在 id 更改时重新渲染组件,它不应该重新渲染组件,否则之前的警告应该无需任何更改即可呈现

我应该如何实现这一目标。我知道我们可以使用 usememo 但无法弄清楚。 如果我使用 my_id ? 它完全删除了警告,但它不应该删除警告,而是显示之前的警告。

我尝试添加 if (id !== '' && id != null) {fecth the api },这不起作用。

reactjs react-hooks react.memo
1个回答
0
投票

这里讨论了一种模式,即“当道具发生变化时调整某些状态”。这可能适用于您的情况。 都是关于如何根据道具调整状态。一般是通过useEffect来完成的。但是,它的缺点是渲染状态会陈旧。此过时的渲染随后将由 useEffect 中的状态更新程序重新渲染。上面的模式专门解决了避免陈旧渲染的问题。

在此模式中,状态在渲染期间发生变化。每当渲染期间状态发生更改时,React 都会丢弃渲染返回的 JSX,并尝试进行另一个渲染。通过这种方式,可以避免使用 useEffect 时发生的陈旧渲染。

下面给出了示例代码。您可以利用代码中给出的注释。

App.js

import { useState } from 'react'; export default function App() { const [changedState, setChangedState] = useState(Math.random()); return ( <> <Component changedProps={changedState} /> <br /> <button onClick={() => setChangedState(Math.random())}> Change props with a random value </button> <br /> <button onClick={() => setChangedState(null)}> Change props with a null value </button> <br /> </> ); } function Component({ changedProps }) { const [adjustedState, setAdjustedState] = useState(changedProps); const [prevProps, setPrevProps] = useState(null); // if there is a change in the props if (changedProps !== prevProps) { if (changedProps) { // When the new value is truthy // then set the component state to the new value // and initiate a new render. // Meantime keep track of the previos value as well. setPrevProps(adjustedState); setAdjustedState(changedProps); } else { // When the new value is falsey // then set the component state to the previous value // but cancel the previous value as well. setAdjustedState(prevProps); setPrevProps(null); } } return ( <> Adjusted State value : {adjustedState} {console.log(`JSX for the state : ${adjustedState}`)} </> ); }

试运行

加载应用程序时。

控制台日志显示了两组 JSX,但是这里只发生了一次渲染。

第一组 JSX 将被丢弃,因为在第一次渲染期间已经调整了状态。并且会立即触发另一个渲染。第二次渲染不会改变渲染过程中的状态,因此会以正常方式完成渲染。*

Browser display - On loading the app

点击按钮“用随机数更改道具”

正如第一次测试运行中所讨论的,这里也将有两组 JSX,但只有一个渲染。

Browser display - On clicking the button random value

单击按钮 - 更改具有空值的道具

一切都按照之前的情况发生。第二次渲染仍然以先前的状态值发生。这可以在控制台日志中看到。

Browser display - On clicking the button - null value

© www.soinside.com 2019 - 2024. All rights reserved.