DEV Community

Ghost
Ghost

Posted on

3

State and Variable in React Hooks

I am pretty new to react-hooks and I have yet to discover its real super powers. I want to ask if I am breaking anything if I do the sample code below.


let somevariable= [];

const SomeComponent = () => {
  const [state, setState] = useState({});

  useEffect(()=>{
   fetch('http://insert-api/state')
      .then(response => response.json())
      .then(data => setState({ data }));
  },[])


  useEffect(()=>{
   //update `somevariable` whenever the state changes
   somevariable = state.something
  },[state])


 const clickMe = () => {
   console.log(somevariable)
   //do something to somevariable
 }

  return (
    <button onClick={clickMe}>Click Me </button>
  )
}

Instead of putting somevariablein the state I put it outside to make it kind of global. I did this because when I put somevariable in its own state and set its value in the useEffect it results to endless loop but this one does not, so this is like my workaround. A lot of my functions rely on somevariable that's why it's important for me to know if this approach is alright or not.

PS. I don't know if it's alright to ask this here so please tell me if it's not and I will take it down. Thanks.

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (1)

Collapse
 
dance2die profile image
Sung M. Kim • Edited

When you put the somevariable outside of React's control, changing the value of somevariable would not trigger components depending on that value to re-render.

e.g.)

You can fork and try it yourself

Edit Doesn't re-render with global variable

let somevariable;

const Child = ({ somevariable }) => {
  useEffect(() => {
    console.log(`Child rendering with somevariable=>`, somevariable);
  });

  return <h1>{somevariable}</h1>;
};

async function fetchData() {
  return "some data";
}

const SomeComponent = () => {
  const [state, setState] = useState({});

  useEffect(() => {
    fetchData().then(data => setState({ data }));
  }, []);

  useEffect(() => {
    //update `somevariable` whenever the state changes
    somevariable = state.data;
  }, [state]);

  const clickMe = () => {
    console.log(somevariable, state);
    //do something to somevariable
  };

  return (
    <>
      <button onClick={clickMe}>Click Me </button>
      <Child somevariable={somevariable} />
    </>
  );
};

You can see that Child that depends on the change of somevariable does NOT render, as somevariable is not a state tracked by React.

The demo below doesn't render the Child component (with <h1>{somevariable}</h1> element)

does not rerender

Can you post a runnable code (possibly forking the sandbox) that causes the infinite loop?