Search code examples
javascriptreactjsmaterial-uimui-x-data-grid

How do I update React component on a global variable change?


I have a React component that shows details of a soccer game when that game is clicked on in a table, called GameData. The table is part of another component, and it updates a variable that GameData uses to show the data. That variable is global, so using useState() inside of GameData doesn't work. How do I make GameData re-render when the variable updates/changes?

Here is what my GameData component is currently:


let gameToDisplay = {};

function displayGameData(gameId) {
    gameToDisplay = gameData.find(game => game.id === gameId);
    // This function runs when a game in the table is clicked. This part updates and works as expected. 
}

function GameData() {
    const [gdDisplay, setgdDisplay] = useState(true);

    function handleDetailClick() {
        setgdDisplay(!gdDisplay);
    }

    return (
        <div className='GameData box'>
            <h2>Game Details</h2>
            <div className='Links'>
                <ButtonGroup variant="contained" aria-label="outlined primary button group">
                    <Button onClick={handleDetailClick}>{gdDisplay ? 'Less' : 'More'} details</Button>
                </ButtonGroup>
            </div>
            {gdDisplay ? (
                <p className='data'>
// Data display that gets data from gameToDisplay 
                </p>
            ) : ( 
                <></> 
            )}
        </div>
    )
}

Yes, the button approach works, but you have to click the button twice for the data to update. I'm trying to change the data inside of <p className='data'> when gameToDisplay is changed. How can I watch for that variable to change and re-render <p className='data'> when that happens?


Solution

  • How do I update React component on a global variable change?

    You don't. Don't use global variables. Use state.

    State doesn't have to be local to this exact component. If this component needs to be re-rendered based on a state change in another component, you have a variety of options:

    • Lift state up so that it's managed by a common parent component and passed to the child components as props.
    • Use the useContext hook to manage state outside of the components.
    • Use a custom hook which manages the state outside of the component(s) and provides access to reading and setting that state within any component which needs it.
    • Use a "global" state management system which manages state outside of the components and allows components to subscribe to that state.

    Basically, overall you're thinking about it the wrong way. You're trying to use React without using React by managing "state" manually in your global variables and re-rendering components manually with your own logic.

    Don't.

    React manages state updates and component re-renders. That's its core functionality. So if your goal is to use React then, well, use React.