javascript - 如何从自定义 React hook 返回变异值?

标签 javascript reactjs react-hooks use-effect

我想将组件状态传递给自定义 Hook ,如果我的状态与初始状态相比发生变化,则返回 true。


import { useRef, useEffect } from 'react'

export const useDirtyState = (props:any) => {
//Possibly use local state and set it to true and return that

  const isFirstRender = useRef<boolean>(true)
  const isDirty = useRef<boolean>(false)

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false
      return
    }
    isDirty.current = true
    console.log(isDirty.current) // is true
  }, [props])
  console.log(isDirty.current) // I return this and it is false :(
} 

//In some other component 
const isDirty = useDirtyStaate(state)//Expect this to be true when state is changed

问题是即使 props 发生变化,外部 console.log 也会显示 false,因为我的效果在那之后运行(我猜?)。如何从此 Hook 返回正确的值?


编辑:我尝试向 Hook 添加本地状态并将其设置为 true 并返回它。虽然这种方法有效,但我想知道是否有更干净的方法,因为它似乎会导致 1 次额外的渲染。

最佳答案

只需将原始值存储在引用中并将其与渲染期间提供的值进行比较:

const {useRef, useState} = React;

// You can implement the value comparison using your preferred method
function areValuesEqual (value1, value2) {
  return Object.is(value1, value2);
}

/**
 * TS:
 * function useValueChanged <T>(value: T): boolean
 */
function useValueChanged (value) {
  const originalRef = useRef(value);
  return !areValuesEqual(originalRef.current, value);
}

function Example () {
  const renderCountRef = useRef(0);
  renderCountRef.current += 1;
  const [count, setCount] = useState(0);
  const increment = () => setCount(n => n + 1);
  const didChange = useValueChanged(count);
  
  return (
    <div>
      <div>Render count: {renderCountRef.current}</div>
      <div>Changed: {didChange ? 'Yes' : 'No'}</div>
      <button onClick={increment}>Clicks: {count}</button>
    </div>
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a8dacdc9cbdce8999f8698869a" rel="noreferrer noopener nofollow">[email protected]</a>/umd/react.development.js"></script>
<script src="https://unpkg.com/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bcced9dddfc891d8d3d1fc8d8b928c928e" rel="noreferrer noopener nofollow">[email protected]</a>/umd/react-dom.development.js"></script>

<div id="root"></div>

关于javascript - 如何从自定义 React hook 返回变异值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68675123/

相关文章:

javascript - 借助弹性弹跳,Chrome/Safari 知道我的手指何时离开触控板。 JS能知道吗?

javascript - 以编程方式滚动时是否保证触发 'scroll' 事件?

javascript - Marionette - 监听从集合触发的自定义事件

javascript - React 将图像 src 设置为动态路径

node.js - 创建 React 应用程序在开发中不使用 Express 重新加载

reactjs - 如何解决警告 "Warning: Can' t perform a React state update on an unmounted component."from setInterval function?

javascript - 移动混合应用程序中的 Jquery Cookie 使用

javascript - React Hook useEffect 缺少依赖项数组

javascript - 使用带依赖项的 useEffect 钩子(Hook)时,什么时候触发清理功能?

javascript - 在带有 setState 的 React 类组件中使用箭头函数的最佳实践