0
votes

We have useState, useReducer in react where after changing a variable created by them the component rerenders. But we can also create variable with useRef and simply with let and const. I got lost in what cases do we have to create variables with useState, useReducer what without? As far as I understand if we need to show variable in a DOM then we use useState and useReducer and for calculation we use useRef or just regular let and const? Am I right?

For instance if I read value of scrollY, I should store it in variable created by let, if I store input value I should use useState ?

export default function(){
    let scroll = useRef(0); // this ?
    let scroll = 0 // this ?
    let (scroll, changeScroll) = useState(0) or this // or this ?

    // scroll var
    useEffect(() => {
        window.addEventListener("scroll", () => {
            scroll = window.scrollY;
        })
        return () => {
            window.removeEventListener("scroll",() => {
                scroll = window.scrollY;
            });
        }
    }, [])
1
If I understand the question correctly, you basically want to know when to use standard variables (const, let) and when to use React hooks (useRef, useState) to store information in a function component? If so you should read the React Hooks Overview and React Hooks API Reference as they outline when to use each different hook.FoundingBox
Regarding your assumptions in the question, I would say that they aren't necessarily true. Any type of variable value can be used as part of the JSX and rendered to the DOM, and calculations can be done in any of the different ways to store variables. From reading the documentation I linked above, you'll see that the decision making process is more based on "how is this value used in the component lifecycle".FoundingBox

1 Answers

1
votes

You should be using useState for variables that represent the state of your component, such as values of text fields, whether a checkbox is checked or not and other values you want to persist between renders.

const[text, setText]=useState('defaultText')
return (<input value={text} onChange={(e) => setText(e.target.value)} />)

For variables you do need to persist you can create normal variables, they will be re-initialised each time your component renders.

let temp = doSomeCalculations()
if(temp>1000)
    updateState()
doSomethingElseAndForgetAboutTemp()
    

scroll in your example should be an ordinary variable, because it does not represent the state of the component. If you read scroll position of the window into scroll and then the user scrolls away, scroll will not mean anything, similarly, if you update scroll, it won't do anything to the scroll position, so it doesn't make any sense to keep it in the state, you need to read the current value each time the scroll even occurs.

useRef on the other hand, is not supposed to store variables, instead it gives you an ability to directly interact with a child component, such as input or checkbox, which makes it look like an alternative to useState - instead of creating a state variable for an input value, you can read and set the value of the element directly. However, in most cases it is preferable to use state variables, as it makes your code more readable and maintainable.

const[myInput]=useRef()
return (<input ref={myInput} onChange={() => console.log(myInput.current.value)} />)