Quick React Part 3 - Real world scenarios
Posted on October 2, 2021
Tags: javascript
1 Real world scenarios
1.1 Fetch data and setState
```{.js lines} const [getState,setState] = useState(null); function fn_That_setState(){ fetch.then((x)=>setState(x)) }
function fn_That_uses_getState(){ fn_That_setState() //BAD NEVER DO THIS //getState = null // setState is not immediate doSomething(getState) //ERROR null state }
* Why?
* `fn_That_setState()` call, the state is not updated immediately
* `doSomething(getState)` reduces to `doSomething(null)`
```{.txt filename=badMentalModel}
setState,getState
/ \
/ \
fetch doSomething(getState) !!ERROR
setState | getState
/ | \
/ | \ fetch | doSomething(getState)
1.2 EventListeners lost on rerender
On rerender the vanilla JS let
variables and eventlisteners in the localenv are “reset”
Basically everything gets reinitialized except the useState
useRef
variables
- Solution is to wrap the canvas and toggle variable in useRef
- below
toggle.current
is unaffected by rerenders - allow the event listener to be rebuilt each time
- below
const Junk = () => {
let toggle = useRef(true); //GOOD
//let toggle = true; //BAD, resets every render
const width = 300;
const height = 300;
const [nully,forceRender] = useReducer(x=>x+1,0);
useEffect(()=>{
const toggleDraw = (e) => {
if(toggle.current == true){
let mX = e.clientX - width;
let mY = e.clientY - height;
console.log(tempX,tempY);
}
}const toggleCallBack = (e) => {
if(e.code == "KeyG"){
.current = !toggle.current;
toggle
}
}document.addEventListener("mousemove",toggleDraw,false);
document.addEventListener("keydown",toggleCallBack,false);
return(()=>{
console.log("unlinked") //called every rerender
document.removeEventListener("mousemove",toggleDraw,false);
document.removeEventListener("keydown",toggleCallBack,false);
});
})return(
<div>
<canvas id="tutorial" width={width} height={height} style={{border: "1px solid black"}} />
<input type="button" value="hi" onClick={(e)=>{console.log(toggle)}}/>
<input type="button" value="force" onClick={(e)=>{forceRender()}}/>
</div>
) }