在 React 中創建函陣列件并設定默認引數時,一切都按預期作業,并且組件將被渲染一次。但是一旦你添加了一個像這樣的鉤子useEffect并在依賴陣列中使用這個引數,組件就會永遠重新渲染。我在這里創建了一個簡單的演示:https : //codesandbox.io/s/infinite-useeffect-loop-on-default-value-tv7hj?file=/ src/ TestComponent.jsx
原因很明顯,因為當使用一個物件作為默認引數時,它會被再次創建并且不會等于前一個。當然,這不會發生在原始默認引數值(如數字或字串)上。
除了使用之外,還有沒有更好的方法可以避免這種副作用defaultProps?
uj5u.com熱心網友回復:
是的,不要將valueto的默認值設定為物件,只需將其設定為 false。然后檢查是否value為真,如果是,則訪問正確的屬性,否則,僅顯示默認值。新代碼。
它會是這樣的:
import { useEffect, useState } from "react";
const TestComponent = ({ value = false }) => {
const [calcValue, setCalcValue] = useState(0);
useEffect(() => {
setCalcValue((cur) => cur 1);
}, [value]);
return (
<div>
{value ? value.name : "Test"}:{calcValue}
</div>
);
};
uj5u.com熱心網友回復:
你得到無限回圈的原因是因為參考value不斷變化。
第一次渲染組件時,它看到對 value 的新參考,這會觸發useEffect,進而修改組件的狀態,這會導致新的渲染,這會導致value再次重新創建,因為舊的對該變數的參考已更改。
解決這個問題的最簡單方法是在組件外部創建一個默認值并使用它(與defaultProps解決方案基本相同):
import { useEffect, useState } from "react";
const defaultValue = {name: "Test"}; // <-- default here
const TestComponent = ({ value = defaultValue }) => {
const [calcValue, setCalcValue] = useState(0);
useEffect(() => {
setCalcValue((cur) => cur 1);
}, [value]);
return (
<div>
{value.name}:{calcValue}
</div>
);
};
這樣做將確保每次渲染組件時,它都會看到相同的 參考value,因此useEffect鉤子只運行一次。
解決這個問題的另一種方法是首先用 包裹你的組件memo,然后創建一個新的狀態變數,它采用原始的value,并使你的useEffect鉤子依賴于這個新的狀態變數:
const TestComponent = React.memo(({ value = {name: "Test"} }) => {
const [calcValue, setCalcValue] = useState(0);
const [myValue, setMyValue] = useState(value);
useEffect(() => {
setCalcValue((cur) => cur 1);
}, [myValue]);
return (
<div>
{myValue.name}:{calcValue}
</div>
);
});
我們用 包裹組件的原因memo是,如果prop 的值(而不是reference)發生了變化,它只會在狀態更改后重新渲染。您可以memo通過提供自定義比較函式作為第二個引數來更改檢測道具更改的方式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/357925.html
標籤:javascript 反应
上一篇:回圈顏色
