我总是忘记在 React 的useEffect
钩中添加空的依赖项数组以仅运行一次效果。这就是为什么我决定使用一个自定义钩子,其名称中有一个明确的意图,只在挂载上运行一次。但我不明白为什么它运行两次?
import React from "react";
import "./styles.css";
function useOnMount(f) {
const isMountedRef = React.useRef(false);
console.log("ref1", isMountedRef.current);
if (!isMountedRef.current) {
f();
isMountedRef.current = true;
console.log("ref2", isMountedRef.current);
}
}
export default function App() {
useOnMount(() => {
console.log("useOnMount");
});
return <div>Hello useOnMount</div>;
}
下面是输出:
ref1 false
useOnMount
ref2 true
ref1 false
useOnMount
ref2 true
我使用ref
钩子在渲染之间保持可变标志。但我不明白为什么isMountedRef.current
在第一次渲染时true
并在第二次渲染🤔时恢复为false
你总是忘记依赖数组?为什么不记得在你的自定义钩子中写一次呢?
function useOnce (once) {
return useEffect(once, [])
}
在您的App
中使用它 -
function App () {
useOnce(_ => console.log("useOnce"))
return <div>hello</div>
}
这是一个演示 -
const { useEffect, useState } = React
function useOnce (once) {
return useEffect(once, [])
}
function App () {
useOnce(_ => alert("Wake up. It's time to make candy!"))
const [candy, setCandy] =
useState(0)
const earn =
<button onClick={_ => setCandy(candy + 1)}>
Make candy
</button>
const spend =
<button onClick={_ => setCandy(candy - 10)}>
Buy Chocolate (10)
</button>
return <div>
<b>Candy Box</b>
<p>Alert will only appear one time after component mounts</p>
<p>
{earn}
{(candy >= 10) && spend}
</p>
<p>You have {candy} candies</p>
</div>
}
ReactDOM.render(<App/>, document.body)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
这个对我有用,不会生成react-hooks/exhaustive-deps
警告。
function useOnce (once) {
const [ res ] = useState(once)
return res
}
用法:
function App () {
useOnce(() => {
console.log("useOnce")
// use any App props or result of other hooks
...
})
return <div>hello</div>
}
这里推荐用于另一项任务,但它作为componentDidMount
替代品效果很好。任何参数都可以在函数中使用。只要确保你真的不需要监控道具的变化。