James Penner
James Penner

Reputation: 81

React context magically change other state

Can anyone explain this thing? Why does other state magically change value when I modify a context? title here is modified when I change someState even though these 2 value never interact with each other at all

const LapContext = React.createContext();

function Btn(arg){
    
    return <div onClick={arg.click} className="btn" style={{display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "15px", width: "275px", height: "6em", outline: "1px solid orange"}}>
                <p style={{color:"rgb(255,165,0)", fontSize: "2em"}}>{arg.val}</p>
            </div>
    
}

function Control(arg){
    
    let [someState, setSomeState] = React.useContext(LapContext);
    
    function setTitle(){
        
        arg.setter("asdasd");
        
    }
    
    function changeSomeState(){
        
        setSomeState(["a"]);
        
    }

    return  <div>
                <Btn val={"Button1"} click={setTitle}/>
                <Btn val={"Button2"} click={changeSomeState}/>
            </div>
    
}

function Main(arg){
    
    {/*this state is modified for no reason*/}
    let [title, setTitle] = React.useState("default");

    return <div>

            <p style={{fontSize: "3em", color: "yellow"}}>{title}</p>
            <Control setter={setTitle}/>

    </div>
    
}

function Page(){
    
    {/*this state is shared with context*/}
    let [someState, setSomeState] = React.useState(["some value"]);
    
    return <LapContext.Provider value={[someState, setSomeState]}> 
    <Main key={uuid.v4()}/>
    </LapContext.Provider>
            
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Page/>);

Upvotes: 1

Views: 209

Answers (1)

Nadia Makarevich
Nadia Makarevich

Reputation: 104

You have quite a few problems in your code, for example, you shouldn't pass imperative API like that, should rely on props/onChange callbacks API instead, it's more React way. Take a look at React docs on how components should interact with each other:

https://reactjs.org/docs/components-and-props.html

But if you just want an answer to the question, then the problem is here:

<Main key={uuid.v4()}/>

You generate a unique key on every re-render. This will cause React to identify the entire component as a "new" component among its siblings, un-mount it, and mount it back from scratch. Which results in your state "resetting" to the default one.

"key" is usually used in the List-like components, you don't need it here. Just remove it and the state will go back to "normal" behaviour.

Upvotes: 1

Related Questions