只在更新时运行 effect
这是个比较罕见的使用场景。如果你需要的话,你可以 使用一个可变的 ref 手动存储一个布尔值来表示是首次渲染还是后续渲染,然后在你的 effect 中检查这个标识。(如果你发现自己经常在这么做,你可以为之创建一个自定义 Hook。)
function Example () {
const [count, setCount] = useState(0);
const prevCountRef = useRef(false);
useEffect(() => {
if (prevCountRef.current) {
console.log('只在更新时候执行')
} else {
prevCountRef.current = true
}
});
return (
<div>
<div>{count}</div>
<button onClick={() => {setCount(count+1)}}>+</button>
</div>
)
}
这或许有一点错综复杂,但你可以把它抽取成一个自定义 Hook:
function Example () {
const [count, setCount] = useState(0);
const update = useUpdate()
console.log(update, '是否更新')
return (
<div>
<div>{count}</div>
<button onClick={() => {setCount(count+1)}}>+</button>
</div>
)
}
function useUpdate () {
const ref = useRef(false)
useEffect(() => {
ref.current = true
})
return ref.current
}
获取上一轮的 props 或 state
目前,你可以 通过 ref 来手动实现:
function Example () {
const [count, setCount] = useState(0);
const prevCountRef = useRef();
useEffect(() => {
prevCountRef.current = count
});
const prevCount = prevCountRef.current
console.log(prevCount, count, '之前的状态和现在的状态')
return (
<div>
<div>{count}</div>
<button onClick={() => {setCount(count+1)}}>+</button>
</div>
)
}
这或许有一点错综复杂,但你可以把它抽取成一个自定义 Hook:
function Example () {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count)
console.log(prevCount, count, '之前的状态和现在的状态')
return (
<div>
<div>{count}</div>
<button onClick={() => {setCount(count+1)}}>+</button>
</div>
)
}
function usePrevious (value) {
const ref = useRef()
useEffect(() => {
ref.current = value
})
return ref.current
}
函数中看到陈旧的 props 和 state
组件内部的任何函数,包括事件处理函数和 effect,都是从它被创建的那次渲染中被「看到」的。
function Example () {
const [count, setCount] = useState(0);
function handleAlertClick () {
setTimeout(() => {
console.log(count)
}, 3000)
}
function increment () {
let newCount = count + 1;
setCount(newCount)
}
return (
<div>
<div>{count}</div>
<button onClick={increment}>+</button>
<button onClick={handleAlertClick}>点击</button>
</div>
)
}
如果你刻意地想要从某些异步回调中读取 最新的 state,你可以用 一个 ref 来保存它,修改它,并从中读取。
function Example () {
const [count, setCount] = useState(0);
const ref = useRef(0)
function handleAlertClick () {
setTimeout(() => {
console.log(ref.current)
}, 3000)
}
function increment () {
let newCount = count + 1;
setCount(newCount)
ref.current = newCount
}
return (
<div>
<div>{count}</div>
<button onClick={increment}>+</button>
<button onClick={handleAlertClick}>点击</button>
</div>
)
}
请记住,当 ref 对象内容发生变化时,useRef 并不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调 ref 来实现。
————————————————
版权声明:本文为CSDN博主「前端精髓」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wu_xianqiang/article/details/100037632