useState not registering on first render - reactjs

I have a very simple react application. I am trying to set a state variable and then immediately after console.log that variable but am getting a blank value.
var [techFilterTerm, setTechFilterTerm] = useState('');
setTechFilterTerm('Test');
console.log(techFilterTerm);
I expect on the first render this would show "Test" in the console - it however shows the empty string. What is going on here?

If I understand your problem correctly you want to know the updated value and for that you can use useEffect api which will get called whenever there is change in one of the value you want to observe. The values you want to observe you need to pass as second parameter as array in useEffect. In your case you want to know the updated value for techFilterTerm so you can pass techFilterTerm as second argument to useEffect as below.
useEffect(() => {
//here you will get the updated value whenever there is change in value
},[techFilterTerm]);
here is the link for more info on useEffect.
https://reactjs.org/docs/hooks-effect.html

Related

React useState array stays empty on first update

const [liveRows, setLiveRows] = useState([]);
function addRow(arr){
setLiveRows([...liveRows, arr]);
console.log(liveRows)
}
When I run the addRow function with an array, the map used in the page re-renders fine, but the array in the log shows empty.
Running the function again shows the previous state of the array before the update, but the re-render shows correctly.
I am assuming this is due to the spread but am lost how to correct it?
This is expected behavior. setState is not an asynchronous! setState always work after the next render.
The set function only updates the state variable for the next render. If you read the state variable after calling the set function, you will still get the old value that was on the screen before your call.
For details : https://beta.reactjs.org/reference/react/useState

React js state value late update

set the state value in Useeffect function and want to use that value after 5 lines in filter function but the state show the empty value means it update the state late how to solve this error
setState is an asynchronous function. Let's take this example
const [testState, setTestState] = useState()
and in a useEffect, if you call lets say setTestState('1234') and the very next line you try to log it console.log(testState) - this wont log '123' as the setTestState is asynchronous, which is happening in your case.
Solution -
Put the filter function in a different useEffect and pass the state in the dependency array

D3 Graph displays no graph despite no errors (REACT)

Im trying to port the code from https://www.d3-graph-gallery.com/graph/correlogram_scatter.html to react.
Now I know there are multiple things I need to change such that I don't create a new SVG on every new re-render, I just wanted to make sure I could get the example graph working before I started to make changes.
However nothing renders, and the console has no errors which makes debugging this very difficult.
I threw an example into code sandbox that seems to mimic what I see on my end.
What am I missing?
https://codesandbox.io/s/compassionate-haze-9excy?file=/src/App.js
Looks like what this might need to get over the finish line is wrapping our D3 code in React's useEffect hook.
Here's an updated, working Codesandbox.
We can call useEffect initially and we can pass any data we'd like to observe for our chart in the array that useEffect takes as an argument.
This works well because useEffect is called the first time that DOM elements have been rendered, which is why it's the best time to access the DOM element living in the properties of the svg ref.
Every time your component renders, it calls useEffect. You can watch for changes by passing arguments into its array, but if you only want to run useEffect the very first time the component mounts, you can leave that array empty.
In my experience, this has been a helpful pattern:
function YourChartCode({ data, property }) {
const yourRef = useRef();
// will be called initially and on every data change
useEffect(() => {
const svg = d3.select(yourRef.current);
// do D3 stuff here
// leave array empty or pass arguments you're watching into this array
}, [data, dimensions, property])
return (
<svg ref={yourRef}></svg>
)
}

Dependencies in React useEffect cleanup function are not updated

I am facing a strange issue when trying to call a cleanup function on component unmount with useEffect.
In my useEffect return I call a useCallback function where the dependencies are added correctly. In there a check the state variable called status but this variable never get updated from the initial state. I cannot pass the variable to the useEffect as I want to trigger it only when the component unmounts for specific reasons.
I recreated a simplified version in the codepen here and I can't get my head around this. Maybe someone knows why this is happening?
Thank you!
(this just started happening recently and it was working previously so I'm even more confused!)
Thank you for your answers.
So, I finally found out what happens.
useEffect creates a closure and the function is in that closure, which means that the status, being a string, remains as for the first render (when the closure gets created) and it never gets updated.
A way of giving this is using useRef, as mentioned by #ilkerkaran, but that's because it creates an object, which means that the ref.current property has a link to the original one and it's always in sync.
Another way would be to do useMemo and return an object with the status property, which is practically useRef under the hood.
So practically, if the state were an object and we passed state as a dependency, the stayus property would work as expected for the same reason. I hope this helps also someone else and saves some time
Actually that's not what happens on your code. The callback function is updated according to dependency array. You can see that by calling remove() just above useEffect. That way, the func will be executed on every render.
What happens in your example;
it renders, (by pressing the toggle button for the first time)
then you trigger second render by calling setStatus("mounted") in useEffect (by pressing the toggle button for the second time)
then it renders for te last time for unmount with the default state values
Last part also bugs me actually. You can observe this behaviour by putting a simple console.log just above your useEffect definition.
You also can work around this by using useRef instead of useState
The reason for this is your useEffect .
React.useEffect(() => {
setStatus("mounted")
return () => remove()
}, [])
You have an useEffect with the dependency set to []. This means that your useEffect will run only once . So this is how the flow goes your component is executed from the top to bottom so you create a remove function which at this point of time has your initial state as not mounted . Now your dom get painted. You useEffect gets called you set the state now you get a brand new remove function . Now you unmount your component the clean up will use the remove function from the first render.
In order for your state to reflect in the remove you need to add status as the dependency in the useEffect .
React.useEffect(() => {
setStatus("mounted")
return () => remove()
}, [status])

Update a state variable only on loading the page for the first time in react js

I have a react component and I want to update the state variable to be false when the page loads for the first time. I am using useEffect for that, but later down the page I am using a third party library that calls a function which has a function to update the same state variable to be true and that is what I want but that runs the useEffect again which makes it back to false.
So, I want to make sure the state variable to be only false when we load/refresh the page
useEffect(() => {
Dosomething();
DoAnotherThing();
changeState();
}[Dosomething,DoAnotherThing,changeState]);
return (
<>
<ThirdPartyComponent>
//on Load dispatches another function
AnotherFunction();
</ThirdPartyComponent>
</>
)
Actions
AnotherFunction(){
changeState(); //I want the state change to happen here but it calls the useEffect back again which makes it false
}
So, I am trying to make sure that state variable is false only on load/refresh of the page. I am using Redux for state management
Your useEffect is triggered every time your component is re renderer, if you want it to run only when the component is mounted, you should use useEffect with an empty array as a second argument.
useEffect(() => {//stuff},[])
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.
Here
Pass a blank array as second argument of useEffect.
useEffect(() => {
changeState();
}, []);

Resources