【问题标题】:React.js run useEffect before useState set default valuesReact.js 在 useState 设置默认值之前运行 useEffect
【发布时间】:2020-12-16 12:05:59
【问题描述】:

我有一个名为employee.js 的反应组件。我使用这个组件来创建员工和更新员工。 我管理一个名为isUpdate 的状态。

useEffect 钩子的帮助下,我更改了isUpdate=true。这意味着该组件可用作更新组件。 isUpdate 的默认值为 false。

我使用 formik 来做验证部分。

useEffect(() => {
        if (props.location.state && props.location.state.update) {
            // update
                        
            console.log('line 1')
            
            getEmp(props.location.state.id);
            
            console.log('line 2')
        }
    }, [props.location.state, console.log('initial values', initialValues)]);

这是我的useEffect 钩子代码。请注意控制台记录“第 1 行”“第 2 行”和“初始值”之一。

我的问题是在line 1 之前打印初始值。所以当时初始值为空。但是这些值被设置为 formik 形式。即使在初始值更改后,它也不会反映在 UI 中。

我来自 vuejs 世界,刚开始做出反应。在 vuejs 中,它创建了生命周期钩子。它在任何事情之前运行。这里的组件似乎在 useEffect 钩子之前就已经加载了。

如何在反应世界中解决这个问题?

【问题讨论】:

  • 你能展示你的整个组件还是更多组件?
  • 我假设您正在记录 initialValues 只是为了检查它是什么……但您是在依赖项数组中进行的。为什么?另外,initialValues 是什么,在哪里使用?
  • 你在 useEffect 钩子中的第二个参数不应该这样使用。那是依赖数组,它只会对特定状态或道具的变化做出反应。不要把console.log放在那里

标签: javascript reactjs formik


【解决方案1】:

useEffect 在创建 DOM 并且渲染已提交到屏幕后运行。所以如果你想在渲染之前做点什么,你会想看看useLayoutEffect。大多数时候,useEffect 是您所需要的,您只需要考虑异步数据流即可。

useEffect 将运行每个渲染,除非您提供依赖数组。如果您提供一个依赖数组,useEffect 只会在第一次运行,并且每次该值数组更改时(不是数组本身,因为它的内存地址通常会在每次渲染时更改)。我相信它执行的是浅层比较,因此在使用依赖列表中的对象时要小心(mutable.js 非常适合)。

有了这两条信息,你就能明白为什么你的代码有点奇怪了。

您调用useEffect 并使用要运行的函数和[props.state.location, console.log(...)] 的依赖项列表,这意味着useEffect 将第一次运行,并且随时props.state.location 更改。它看起来像是一个对象,所以每当该对象的内存地址发生变化时。第二个参数将始终未定义,因此在这种情况下并不是真正有用。

您指出日志发生在useEffect 函数运行之前。这是有道理的,因为它是useEffect 的参数,并且必须在调用useEffect 方法之前评估参数。

让我们重新审视您的问题。听起来您正在使用在 initialValues 上设置的名为 Formik 的东西,但是它发生在第一次渲染之后,并且没有触发新的渲染?我需要查看更多与initialValues 相关的代码,但这是我的猜测。您可能直接在initialValues 上设置一个值,而不是通过useState 进行设置。 React 需要知道何时重新渲染组件,它通过侦听 setState 调用来做到这一点。它不会像 Mobx 或 VueJS 那样做智能魔法的事情,因此当您更改状态某处的属性时,它不能神奇地重新渲染自己。

// Creates a state variable called isUpdate and initializes it to false.
// On re-renders, it provides isUpdate with whatever value its been updated to
const [isUpdate, setIsUpdate] = useState(false);

// Sometime in the future

// changes state and causes a component to re-render
setIsUpdate(true); 

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2020-11-20
    • 2020-10-22
    • 1970-01-01
    相关资源
    最近更新 更多