[英]Is initial state based on props always bad in React?
React 的一個常見知識是,如果我們不使它們同步,則由 props 初始化 state 是不好的。 這被認為很好:
import { useState, useEffect } from 'react';
export default function MyInput({ initialValue }) {
const [value, setValue] = useState(initialValue);
useEffect(
() => setValue(initialValue),
[initialValue]
);
return (
<>
<h1>The value is {value}</h1>
<input
type="text"
value={value}
onChange={event => setValue(event.target.value)}
/>
</>
);
}
但是,如果我實際上不想在initialValue
更改時更新值並想在此處刪除useEffect()
怎么辦? 它強烈反對 React 哲學嗎? 這對我來說很有意義,因為我實際上不想在其他東西更改作為initialValue
傳遞的值時更新此輸入值。 我不希望用戶在發生這種情況時丟失他們的輸入。
有多糟糕?
本質上,使用 prop 作為 state 變量 AFAIK 的初始值並沒有錯。
但是,在您的示例中,您正在做一些荒謬的事情:您正在定義一個 state 變量,該變量使用道具的值進行初始化,然后每次道具更新時,您都會使用相同的值更新您的 state 。 不管它是否是反模式,它都沒有意義 - 直接使用 prop,你正在做無利可圖的額外工作。 如果您刪除useEffect
,您將非常有效地使用 prop 作為 state 變量的初始值。
在 React.js 中使用派生 state 的問題經常被誤解, 這個 StackOverflow 問題證明了這一點。
在問題提供的代碼示例中,不清楚為什么在可以直接使用initialValue
道具時使用派生的 state。 為了清楚起見,為此目的使用useEffect
將被視為反模式。 相反,您應該自己檢查更改,如React 文檔中所示
但是,如果EmailInput
組件對initialValue
做了一些修改,如果我們遵循“提升 state 的規則” (我相信作者試圖在此評論中解釋),這樣的邏輯將不必要地污染父組件。
在這種情況下,我認為如果謹慎使用,反模式可能是一個可以接受的選擇。 使用上述反模式的Robin Wieruch 博客文章。
另一種解決方案是使用key
屬性( 在這種情況下很有用),但這僅在 key 和initialValue
基於不同狀態時才有效。 否則,可能會導致重復渲染。
具有key
屬性的示例
// EmailInput.jsx
export default function EmailInput({ initialValue, onChange }) {
const [value, setValue] = useState(initialValue);
const handleChange = (event) => {
const newValue = event.target.value;
// do some modification on the newValue
setValue(newValue);
onChange(newValue); // pass value to parent
};
return (
<>
<h1>The Email is {value}</h1>
<input type="text" value={value} onChange={handleChange} />
</>
);
}
// Checkout.jsx
export function Checkout() {
const [user, setUser] = useState({
id: 1,
email: "example@example.com",
});
return (
<>
<EmailInput
initialValue={user.email}
key={user.id}
onChange={(value) => setUser({ id: user.id, email: value })}
/>
<button
onClick={() => setUser({id: 2, email: "foo@bar.com"})}
>
Update user
</button>
</>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.