【问题标题】:why useEffect hook not working as expected - how its related to useState?为什么 useEffect 钩子没有按预期工作 - 它与 useState 有什么关系?
【发布时间】:2020-09-01 03:43:32
【问题描述】:

我是反应钩子的新手,在useEffect 我正在创建函数,该函数将在单击同一组件内的按钮时被调用。但我面临一个问题,每次它使用一个旧道具值,而不是新道具值。我不明白为什么。

如果我在 state 中分配 prop,它会正常工作,即使我没有使用 state 值,只是设置。

Try here

const defaultCalls = () => {
    let fn = (e) => console.log('This is default click fn.');
    return {
        overrideClickCall: (newFn) => {
            fn = newFn
        },
        clickFn: (e) => {
            fn(e);
        }
    }
}

let dCalls = defaultCalls();

const anotherFn = (e, userName) => {
  console.log(userName);
}

const MyComp = props => {
  let newFn = (e) => anotherFn(e, props.userName)

  //let [state, setState] = useState(props.userName);//on uncommenting it will work fine

  useEffect(() => {
    //setState(props.userName);  //on uncommenting it will work fine    
    dCalls = defaultCalls();
    dCalls.overrideClickCall(newFn);
    console.log('override default fn')
  }, [props.userName]);

  return (
    <input type="button" onClick={dCalls.clickFn} value="Click Me" />
  )
}

export { MyComp }

【问题讨论】:

  • “在这里尝试”请使用 Stack Snippets([&lt;&gt;] 工具栏按钮)将您的可运行示例在这里,现场。 Stack Snippets 支持 React,包括 JSX; here's how to do one.
  • 对于您所说的您正在尝试执行的操作,该代码看起来非常复杂。 defaultCalls、dCalls等的目的是什么?只需创建一个将用作点击处理程序的函数,您不必做任何特别的事情。如果你愿意,你可以用useCallback 记住它,但通常这不是必需的。似乎您试图做的不仅仅是拥有一个点击处理程序......?
  • 很快就会把sn-p放在这里,默认调用。可以说它是 3rd 方库,做一些复杂的操作,并且还提供了 overriding 的功能
  • 恐怕我无法理解您在该评论中的意思。
  • 考虑defaultCalls 就像我正在使用的一个库,它提供了一种方法,以便您可以覆盖默认的click 处理程序。我覆盖了我的组件的useEffect。

标签: javascript reactjs react-hooks jsx use-effect


【解决方案1】:

让我们考虑一下快照。只要你有一个属性值,组件函数就会使用当前的 props 值执行(函数体内引用任何 props 的所有内容都将替换为实际的 props 值)。在初始设置值之后,执行useEffect。在您的情况下,这意味着这一行:

<input type="button" onClick={dCalls.clickFn} value="Click Me" />

在useEffect 运行以更新您的defaultCalls 之前创建。所以它有一个过时的clickFn 副本。

你如何解决它:而不是onClick={dCalls.clickFn},把它变成一个函数本身:onClick={(e) =&gt; dCalls.clickFn(e)}。

这样做,您将不会在 onClick 事件中使用任何记忆化版本的 clickFn。只有当用户点击按钮时,它才会抓取clickFn,因此,最新版本的clickFn。

顺便说一句,我真的希望你只是在做一些学习实验,因为这段包含如此多的间接代码的代码在短期内会成为枪。

我强烈推荐阅读:https://overreacted.io/a-complete-guide-to-useeffect/

这不是一个简短的阅读,但我可以用手指数数我在开发者文章中看到了多少次关于单个主题的如此透彻的解释。

【讨论】:

  • 感谢@julianobrasil 成功了,实际上我理解我的错误。非常感激。是的,我只是在学习反应的钩子,所以尝试了一下,结果很糟糕。
猜你喜欢
  • 2021-09-21
  • 1970-01-01
  • 2021-11-11
  • 2014-08-04
  • 2021-01-03
  • 2018-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多