简体   繁体   English

React.js 在 useState 设置默认值之前运行 useEffect

[英]React.js run useEffect before useState set default values

I have react componet called employee.js.我有一个叫做employee.js 的反应组件。 I use this component to create employees and update employees.我使用这个组件来创建员工和更新员工。 I manage a state called isUpdate .我管理一个名为isUpdate的状态。

With the help of the useEffect hook I change isUpdate=true .useEffect钩子的帮助下,我更改了isUpdate=true Which means this component works as an update component.这意味着该组件可用作更新组件。 Default value for isUpdate is false. isUpdate默认值为 false。

I use formik to do the validation part.我使用 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)]);

This is my useEffect hook's code.这是我的useEffect钩子的代码。 Please note the console logs "line 1" "line 2" and the "initial values" one.请注意控制台记录“第 1 行”“第 2 行”和“初始值”之一。

My problem is initial values are printed even before the line 1 .我的问题是初始值甚至在第line 1之前打印。 So at that time initial values are empty.所以当时初始值为空。 But these values are set to the formik form.但是这些值设置为 formik 形式。 Even after the initial values changes it doesn't reflect in the UI.即使在初始值更改后,它也不会反映在 UI 中。

I came from vuejs world and new to react.我来自 vuejs 世界,刚开始反应。 In vuejs it had created life cycle hook.在 vuejs 中,它创建了生命周期钩子。 It runs before any thing.它在任何事情之前运行。 Here component seems loading even before the useEffect hook.这里的组件似乎在 useEffect 钩子之前加载。

How can I fix this in react world?我怎样才能在反应世界中解决这个问题?

useEffect is run after the DOM is created and the render has been committed to the screen. useEffect在创建 DOM 并且渲染已提交到屏幕后运行。 So if you are wanting to do something before the render, you'll want to look at useLayoutEffect .所以如果你想在渲染之前做一些事情,你会想看看useLayoutEffect Most of the time, useEffect is what you need and you just need to account for asynchronous data flow.大多数时候, useEffect是你所需要的,你只需要考虑异步数据流。

useEffect will run every render unless you provide a dependency array.除非您提供依赖项数组,否则useEffect将运行每个渲染。 If you provide a dependency array, useEffect will only run the first time, and everytime that array of values changes (not the array itself as its memory address will change every render usually).如果你提供一个依赖数组, useEffect只会在第一次运行,并且每次值数组改变时(不是数组本身,因为它的内存地址通常会在每次渲染时改变)。 I believe it performs a shallow comparison, so you'll want to be careful about using objects in the dependency list (mutable.js is great for this).我相信它执行的是浅层比较,因此您需要小心使用依赖项列表中的对象(mutable.js 对此非常有用)。

With those two pieces of information, you can see why your code is a bit odd.通过这两条信息,您可以了解为什么您的代码有点奇怪。

You call useEffect with the function to run and a dependency list of [props.state.location, console.log(...)] , which means useEffect will run the first time, and anytime props.state.location changes.您使用要运行的函数和[props.state.location, console.log(...)]的依赖项列表调用useEffect ,这意味着useEffect将第一次运行,并且随时props.state.location更改。 It looks like its an object, so whenever that object's memory address changes.它看起来像一个对象,因此只要该对象的内存地址发生变化。 The second parameter will always be undefined and therefore is not really useful in this context.第二个参数将始终是未定义的,因此在这种情况下并没有真正的用处。

You call out that the log happens before the useEffect function runs.您指出日志发生在useEffect函数运行之前。 This makes sense since its a parameter to useEffect , and parameters have to be evaluated before the useEffect method can be invoked.这是有道理的,因为它是useEffect的参数,并且必须在调用useEffect方法之前评估参数。

Let's revisit your question.让我们重新审视你的问题。 It sounds like you are using something called Formik that is being set on initialValues however its happening after the first render, and isn't triggering a new render?听起来您正在使用一种叫做 Formik 的东西,它被设置在initialValues但是它发生在第一次渲染之后,并且不会触发新的渲染? I'd need to see more code related to initialValues but here's my guess.我需要查看更多与initialValues相关的代码,但这是我的猜测。 You are probably setting a value directly on initialValues instead of doing it via useState .您可能直接在initialValues上设置一个值,而不是通过useStateuseState React needs to know when to re-render a component and it does this by listening for setState calls. React 需要知道何时重新渲染组件,它通过监听setState调用来实现。 It does not do smart magical stuff like Mobx or VueJS, and therefore can't magically re-render itself when you change a property somewhere on state.它不会像 Mobx 或 VueJS 那样做聪明的魔法东西,因此当您更改 state 某处的属性时,它无法神奇地重新渲染自己。

// 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); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM