我在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
已更新,因为我可以在控制台中看到日志。
就像设置器setX
无法正常工作或组件无法检测到x
已被更新一样。
我做错了什么?
答案 0 :(得分:1)
对我有用。到底是什么问题?你能举个例子吗?
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>
答案 1 :(得分:1)
在此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')
);
每个状态更改仅调用一次使用效果,我看不到您在组件内部调用状态更新的位置。
如果您要从另一个完全不同的位置更改此组件的状态,则建议您使用提供程序或HOC