我有一个组件可以呈现一些错误/警告
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 获取是正确的,不需要修复,我需要修复的只是它的渲染和重新渲染以及删除警告组件的方式。
我的要求
我应该如何实现这一目标。我知道我们可以使用 usememo 但无法弄清楚。 如果我使用 my_id ? 它完全删除了警告,但它不应该删除警告,而是显示之前的警告。
我尝试添加 if (id !== '' && id != null) {fecth the api },这不起作用。
这里讨论了一种模式,即“当道具发生变化时调整某些状态”。这可能适用于您的情况。 都是关于如何根据道具调整状态。一般是通过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 将被丢弃,因为在第一次渲染期间已经调整了状态。并且会立即触发另一个渲染。第二次渲染不会改变渲染过程中的状态,因此会以正常方式完成渲染。*
点击按钮“用随机数更改道具”正如第一次测试运行中所讨论的,这里也将有两组 JSX,但只有一个渲染。
单击按钮 - 更改具有空值的道具
一切都按照之前的情况发生。第二次渲染仍然以先前的状态值发生。这可以在控制台日志中看到。