[英]Pass useState setter function as a callback
我在 React 組件中使用useState
並且我想將 setter 作為回調的一部分傳遞給另一個函數(這個另一個函數處理一些在組件內無法訪問的邏輯)。
這是簡化的代碼:
function init(canvas, cb) {
...
// Call cb(...) based on internal logic
}
function MyComponent () {
const canvasRef = useRef(null);
const [x, setX] = useState(null);
useEffect(() => {
const canvas = canvasRef.current
init(canvas, function (v) {
console.log(v);
setX(v);
});
}, []);
return <div>
<canvas ref={canvasRef} width="500" height="300"></canvas>
<div}>{x}</div>
</div>
}
問題是,調用回調時x
的值不會更新,除了第一次(當x
停止為null
)。
我知道它被調用了,我知道x
已更新,因為我可以在控制台中看到日志。 就像 setter setX
不起作用或組件不會檢測到x
已更新。
我做錯了什么 ?
這個對我有用。 究竟有什么問題? 能給我舉個例子嗎?
function init(canvas, cb) { cb(100) } function MyComponent () { const canvasRef = React.useRef(null); const [x, setX] = React.useState(null); React.useEffect(() => { const canvas = canvasRef.current init(canvas, function (v) { console.log(v); setX(v); }); }, []); function handleOnClick() { init(canvasRef.current, function (v) { setX(prev => prev + v) }) } return ( <div> <button onClick={handleOnClick}>Change prop x</button> <div>{x}</div> <canvas ref={canvasRef} width="500" height="100" /> </div> ) } ReactDOM.render(<MyComponent />, document.querySelector('#root'))
canvas { background: pink; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>
我試圖在這個repl 中做類似的事情,它工作得很好。
import * as React from 'react'
import * as ReactDOM from 'react-dom'
function foo (cb, value){
return cb(value);
}
function App (props){
const [x, setX] = React.useState(0);
const handleClick = v => {
setX(v);
}
return(
<div>
{x? x: "Hello World"}
<input type="button" value="Press Me" onClick={() => foo(handleClick, x+1)} />
</div>
)
}
ReactDOM.render(
<App />
,
document.getElementById('root')
);
use effect 每次狀態改變只調用一次,我沒有看到你在哪里調用組件內部的狀態更新。
如果你的意思是你想從一個完全不同的地方改變這個組件的狀態,那么我建議你使用 providers 或HOC
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.