React Hook返回函数未调用却自动执行问题求助
问题
尝试创建一个返回可调用函数的React Hook,Hook内部创建该函数,最小复现代码如下:
// fetch.js import { useEffect, useState} from "react"; export const useFetch = () => { const [fn, setFn] = useState(null); useEffect(() => { const fn_ = () => console.log("test") setFn(fn_) }, []); return fn; }
// App.js import { useFetch } from './fetch'; function App() { const fn = useFetch() return ( <div className="App"> hello </div> ); }
已禁用Strict模式:
// index.js const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <App /> );
即使未调用fn(),控制台却输出了"test",函数被自动执行了。
原因
React的useState更新函数有特殊逻辑:当你向setState传递一个函数时,React会将这个函数视为状态更新器,它会立即执行该函数,并把函数的返回值作为新的状态值。
你这里的setFn(fn_)中,fn_是一个函数,所以React直接执行了它,导致console.log("test")被触发,而不是把fn_本身存在状态里。
解决方法
要将函数本身作为状态值存储,有两种常见方式:
方式一:用对象包裹函数
把函数放到对象中,这样传递给setFn的是对象而非函数,就不会被当作更新器执行:
useEffect(() => { const fn_ = () => console.log("test") setFn({ call: fn_ }) }, []); // 调用时使用 // fn?.call()
方式二:传递返回目标函数的更新器
给setFn传递一个箭头函数,让它返回你要存储的函数,这样React会执行这个外层箭头函数,并把返回的目标函数作为状态值:
useEffect(() => { const fn_ = () => console.log("test") setFn(() => fn_) }, []); // 调用时直接使用 // fn?.()
内容的提问来源于stack exchange,提问作者ubi
相关产品推荐
相关产品推荐

