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
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"){
                toggle.current = !toggle.current;
            }
        }
        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>
    )
}