useRef() 比 ref 属性更有用。它可以很方便地保存任何可变值

只在更新时运行 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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.duanlonglong.com/qdjy/836.html