第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在EventEmitter的on('change')函數(shù)中使用鉤子設(shè)置狀態(tài)?

如何在EventEmitter的on('change')函數(shù)中使用鉤子設(shè)置狀態(tài)?

斯蒂芬大帝 2023-09-07 17:01:01
為了學習的目的,我試圖通過從頭開始實現(xiàn)它來分解通量模式的基礎(chǔ)知識。我知道我可以使用類組件解決下面的問題,但為什么它可以與類組件一起使用setState({ ... }),而不可以與鉤子的setValues功能一起使用?正如您所猜測的,問題在于該setValues函數(shù)似乎沒有觸發(fā)新狀態(tài)的重新渲染。我有一種感覺這與閉包有關(guān),但我不太了解它們,所以我將不勝感激任何指導(dǎo)和幫助。店鋪// store.jsimport EventEmitter from "events";class StoreClass extends EventEmitter {    constructor() {        super();        this.values = []    }    addNow() {        this.values.push(Date.now());        this.emit('change')    }    getAll() {        return this.values;    }}const store = new StoreClass();export default store;成分// App.jsimport store from './store';function App() {    const [values, setValues] = useState([]);    const handleClick = () => {        store.addNow();    };    useEffect(() => {        const onChangeHandler = () => {            console.log("Change called");            setValues(() => store.getAll())        };        store.on('change', onChangeHandler);        return () => store.removeAllListeners('change')    }, [values]);    return (        <div>            <button onClick={handleClick}>Click to add</button>            <ul>                {values.map(val => <li key={val}>{val}</li>)}            </ul>        </div>    );}
查看完整描述

2 回答

?
ibeautiful

TA貢獻1993條經(jīng)驗 獲得超6個贊

經(jīng)過幾個小時的修補并再次閱讀反應(yīng)文檔后,我終于可以回答我自己的問題了。簡而言之,問題在于商店中的狀態(tài)并不是一成不變地更新的。


Redux 是 Flux 架構(gòu)的實現(xiàn),在其文檔中說得非常清楚:


Redux 期望所有狀態(tài)更新都是不可變地完成


因此,上面代碼中的罪魁禍首就在addNowstore的函數(shù)中。該Array.push()方法通過附加一個項目來改變現(xiàn)有數(shù)組。執(zhí)行此操作的不可變方法是使用該Array.concat()方法或 ES6 擴展語法(解構(gòu))[...this.values],然后將新數(shù)組分配給this.values.


addNow() {

  this.values.push(Date.now()); // Problem - Mutable Change

  this.values = this.values.concat(Date.now()) // Option 1 - Immutable Change

  this.values = [...this.values, Date.now()] // Option 2 - Immutable Change

  this.emit('change')

}

要查看 React 組件中每個更改的效果,請將鉤子setValues中的函數(shù)更改useEffect為以下內(nèi)容:


setValues((prev) => {

  const newValue = store.getAll()


  console.log("Previous:", prev)

  console.log("New value:", newValue)


  return newValue

})

在控制臺中,很明顯,當存儲中的狀態(tài)可變地更改時,單擊第一個按鈕后,先前的狀態(tài)和新的狀態(tài)將始終相同并引用相同的數(shù)組。但是,當存儲中的狀態(tài)不可改變地更改時,先前的狀態(tài)和新的狀態(tài)不會引用相同的數(shù)組。此外,在控制臺中可以清楚地看到先前的狀態(tài)數(shù)組比新的狀態(tài)數(shù)組少一個值。


為什么使用類組件時狀態(tài)更改會觸發(fā)重新渲染,而使用鉤子時則不會?

根據(jù)類組件的 setState 函數(shù)的React 文檔。


setState() 總是會導(dǎo)致重新渲染,除非 shouldComponentUpdate() 返回 false。


這意味著無論存儲中的狀態(tài)是可變的還是不可變的,當觸發(fā)更改事件并setState調(diào)用該函數(shù)時,React 都會重新渲染組件并顯示“新”狀態(tài)。然而,鉤子的情況并非如此useState。


根據(jù)useState hook的 React 文檔:


如果將 State Hook 更新為與當前狀態(tài)相同的值,React 將退出而不渲染子項或觸發(fā)效果。(React 使用 Object.is 比較算法。)


這意味著當通過改變原始對象來完成對存儲中數(shù)組的更改時,react 在決定再次渲染之前會檢查新狀態(tài)和先前狀態(tài)是否相同。由于先前狀態(tài)和當前狀態(tài)的引用是相同的,因此 React 不執(zhí)行任何操作。為了解決這個問題,商店中的更改必須一成不變地完成。


查看完整回答
反對 回復(fù) 2023-09-07
?
梵蒂岡之花

TA貢獻1900條經(jīng)驗 獲得超5個贊

useEffct 監(jiān)聽值的變化,但 setValues 只存在于 useEffect 中,我認為你根本不需要 useEffect


你可以嘗試這樣的事情:


    // App.js

import store from './store';


function App() {

    const [values, setValues] = useState([]);



    const onChangeHandler = () => {

            console.log("Change called");

            const storeValues = store.getAll();

            setValues(storeValues);

        };


    const handleClick = () => {

        store.addNow();

        onChangeHandler();

        };



    return (

        <div>

            <button onClick={handleClick}>Click to add</button>

            <ul>

                {values.map(val => <li key={val}>{val}</li>)}

            </ul>

        </div>

    );

}


查看完整回答
反對 回復(fù) 2023-09-07
  • 2 回答
  • 0 關(guān)注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號