I have react componet called employee.js. I use this component to create employees and update employees. I manage a state called isUpdate
.
With the help of the useEffect
hook I change isUpdate=true
. Which means this component works as an update component. Default value for isUpdate
is false.
I use formik to do the validation part.
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. Please note the console logs "line 1" "line 2" and the "initial values" one.
My problem is initial values are printed even before the line 1
. So at that time initial values are empty. But these values are set to the formik form. Even after the initial values changes it doesn't reflect in the UI.
I came from vuejs world and new to react. In vuejs it had created life cycle hook. It runs before any thing. Here component seems loading even before the useEffect hook.
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. So if you are wanting to do something before the render, you'll want to look at useLayoutEffect
. Most of the time, useEffect
is what you need and you just need to account for asynchronous data flow.
useEffect
will run every render unless you provide a dependency array. 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). 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).
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. 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. This makes sense since its a parameter to useEffect
, and parameters have to be evaluated before the useEffect
method can be invoked.
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? I'd need to see more code related to initialValues
but here's my guess. You are probably setting a value directly on initialValues
instead of doing it via useState
. React needs to know when to re-render a component and it does this by listening for setState
calls. 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.
// 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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.