Button 組件有一個 onClick 事件偵聽器,它呼叫 changeTheme()。內容組件是一個帶有一些文本的 div,它傳遞了一個主題道具“樣式”。當我單擊按鈕時,主題更改為連續單擊 2 次。之后無論我點擊多少次按鈕,主題都不會改變。這是為什么?
function ParentElement() {
const dark={
color:'white',
backgroundColor:'darkgray',
}
const light={
color:'darkgray',
backgroundColor:'white'
}
const [currentTheme,setTheme]=useState(light)
function changeTheme(e){
//toggle theme
currentTheme==light?setTheme(dark):setTheme(light)
}
return (
<div>
<Button changeTheme={changeTheme}/>
<Content style={currentTheme} />
</div>
)
}
function Content({style}) {
return (
<div style={style}>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</div>
)
}
uj5u.com熱心網友回復:
它在兩次后停止作業,因為您正在比較物件參考,在呼叫setState.
由于currentTheme被初始化為light,第一次呼叫currentTheme == light ? setTheme(dark) : setTheme(light)進入“真正的分支”并將 currentTheme 設定為 dark。然而setTheme——作為 React 中狀態物件的任何變化——回傳一個新的物件參考,所以從這一點開始,currentTheme參考將與 light 甚至 dark 的參考不同,盡管此時主題是暗的。因此,從現在開始,條件總是進入“假分支”,這將主題設定為亮。在 JavaScript 中,您正在執行的物件比較就是參考的比較。您可以通過例如比較主題名稱(字串)來解決問題,因為它將是按值進行比較:
function ParentElement() {
const dark = {
name: 'dark',
style: {
color: 'white',
backgroundColor: 'darkgray'
}
}
const light = {
name: 'light',
style: {
color: 'darkgray',
backgroundColor: 'white'
}
}
const [currentTheme, setTheme] = useState(light)
function changeTheme(e) {
//toggle theme
currentTheme.name === light.name ? setTheme(dark) : setTheme(light)
console.log(currentTheme);
}
return (
<div>
<Button changeTheme={changeTheme}/>
<Content style={currentTheme.style} />
</div>
)
}
uj5u.com熱心網友回復:
您也可以這樣做并存檔。
import React, { useState, useMemo } from "react";
const themes = {
dark: {
color: "white",
backgroundColor: "darkgray"
},
light: {
color: "darkgray",
backgroundColor: "white"
}
};
function ParentElement() {
const [themeMode, setThemeMode] = useState("light");
const changeTheme = (e) => {
//toggle theme
const newThemeMode = themeMode === "light" ? "dark" : "light";
setThemeMode(newThemeMode);
};
const currentTheme = useMemo(() => {
return themes[themeMode];
}, [themeMode]);
return (
<div>
<button onClick={changeTheme}>change Theme</button>
<Content style={currentTheme} />
</div>
);
}
uj5u.com熱心網友回復:
以防萬一您想了解這里實際發生的事情:
light是一個object。當您通過useState(light)react 設定默認主題時,會設定對light物件的參考。
在您的changeTheme處理程式中,您正在檢查currentTheme和light是否參考相同的物件currentTheme==light,而不是檢查它們是否相似。這實際上是一個巨大的差異。第一次單擊時,結果為真,主題切換為深色。
在第二次點擊時,主題切換為淺色,但這次反應是深度復制light引擎蓋下的物件。對燈光物件的參考丟失。每次檢查currentTheme==light,從現在開始結果都是假的,主題永遠不會再切換到黑暗。
要解決此問題,您必須進行 deepEqual 檢查(不推薦)或引入另一個標志或變數來跟蹤當前選定的主題。
uj5u.com熱心網友回復:
Reacts useState 鉤子設定狀態異步,這意味著它不會立即執行。在這種情況下,您可能想要使用 useState 回呼。所以試試這個:
currentTheme === light ? setTheme(() => dark) : setTheme(() => light)
我還會考慮在回呼的幫助下檢查當前主題,以確保與實際狀態進行比較,如下所示:
setTheme((prevTheme) => prevTheme === light ? dark : light)
我學到的是,當您想根據前一個狀態修改您的狀態時,您希望從 statehook 回呼中獲取前一個狀態,以確保您獲得前一個狀態。
uj5u.com熱心網友回復:
首先light將始終為真,因為Boolean({})將始終決議為真...您需要檢查例如themes[key]并基于此進行切換
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/337247.html
標籤:反应
