![](/img/trans.png)
[英]Cannot get the updated the state value useState and UseEffect
[英]Why the event handler function cannot get the updated state object value?
這是我的代碼:
應用程序.js:
import './App.css';
import { useAlarmClock } from "./useAlarmClock";
export default function App() {
const[action,data]=useAlarmClock();
let start=()=>{
action.start();
}
return (
<div className="App">
<button onClick={start}>Start Alarm Clock</button>
</div>
);
}
使用AlarmClock.js
import { useReducer } from "react";
import AlarmClock from './AlarmClock';
let reducer = (state, action) => {
let result = { ...state };
console.log(action);
switch (action.type) {
case "init":
result = { "alarmClock": action.alarmClock }
break;
default: break;
}
return result
}
export function useAlarmClock() {
const [itemList, updateItemList] = useReducer(reducer, {});
let start = () => {
let alarmClock = new AlarmClock();
alarmClock.on("connectionTimeout", () => {
console.log(itemList);
})
alarmClock.start();
updateItemList({ "type": "init", alarmClock })
}
return [{
start: start
}, {
itemList
}];
}
鬧鍾.js
export default class AlarmClock {
constructor() {
let connectionTimeoutHandler;
/*=====================================================================*/
/* To configure handler for varies event */
/*=====================================================================*/
this.on = (eventType, param) => {
switch (eventType) {
case "connectionTimeout":
connectionTimeoutHandler = param;
break;
default: break;
}
};
this.start = () => {
setTimeout(() => {
connectionTimeoutHandler();
}, 5000);
}
}
}
我期望以下 function 的 output:
alarmClock.on("connectionTimeout", () => {
console.log(itemList);
})
應該:
{
"alarmClock":{}
}
然而實際結果如下:
{}
所以,我不知道為什么console.log output 不包含alarmClock object。
在每次渲染時,都會為 itemList 創建一個新的 object,因為它具有不變性,但是您在“connectionTimeout”回調中只有指向 itemList 的第一個實例的鏈接。 您可以使用 ref 掛鈎訪問所需版本的 itemList,因此您需要像這樣執行 smtn:
使用AlarmClock.js
import { useReducer } from "react"; import AlarmClock from './AlarmClock'; let reducer = (state, action) => { let result = {...state }; console.log(action); switch (action.type) { case "init": result = { "alarmClock": action.alarmClock } break; default: break; } return result } export function useAlarmClock() { const [itemList, updateItemList] = useReducer(reducer, {}); const itemListRef = useRef(itemList); itemListRef.current = itemList; let start = () => { let alarmClock = new AlarmClock(); alarmClock.on("connectionTimeout", () => { console.log(itemListRef.current); }) alarmClock.start(); updateItemList({ "type": "init", alarmClock }) } return [{ start: start }, { itemList }]; }
UPD:這是工作示例:
const {useReducer, useEffect, useRef} = React; function App() { const[action,data]=useAlarmClock(); let start=()=>{ action.start(); } return ( <div className="App"> <button onClick={start}>Start Alarm Clock</button> </div> ); } let reducer = (state, action) => { let result = {...state }; console.log(action); switch (action.type) { case "init": result = { "alarmClock": action.alarmClock } break; default: break; } return result } function useAlarmClock() { const [itemList, updateItemList] = useReducer(reducer, {}); const itemListRef = React.useRef(itemList); itemListRef.current = itemList; let start = () => { let alarmClock = new AlarmClock(); alarmClock.on("connectionTimeout", () => { console.log(itemListRef.current); }) alarmClock.start(); updateItemList({ "type": "init", alarmClock }) } return [{ start: start }, { itemList }]; } class AlarmClock { constructor() { let connectionTimeoutHandler; /*=====================================================================*/ /* To configure handler for varies event */ /*=====================================================================*/ this.on = (eventType, param) => { switch (eventType) { case "connectionTimeout": connectionTimeoutHandler = param; break; default: break; } }; this.start = () => { setTimeout(() => { connectionTimeoutHandler(); }, 5000); } } } ReactDOM.render(<App />, document.getElementById("root"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> <div id="root"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.