What I would like to be able to do is to initialize my context with a state and a function that updates that state.
For example, say I have the following:
export default function MyComponent () {
const MyContext = React.createContext()
const [myState, setMyState] = useState('1')
const contextValue = {
currentValue: myState,
setCurrentValue: (newValue) => setMyState(newValue)
}
return (
<MyContext.Provider value={contextValue}>
<MyContext.Consumer>
{e => <div onClick={() => e.setCurrentValue('2')}> Click me to change the value </div>}
{e.currentValue}
</MyContext.Consumer>
</MyContext.Provider>
)
}
The {e.currentValue} correctly outputs '1' at first, but when I click the button, nothing changes.
What I would expect is that e.setCurrentValue('2') would call setMyState('2'), which would update the state hook. This would then change the value of myState, changing the value of currentValue, and making '2' display.
What am I doing wrong?
CodePudding user response:
You would want to return a fragment from the context as one JSX root.
Check here - https://playcode.io/931263/
import React, { createContext, useState } from "react";
export function App(props) {
const MyContext = React.createContext();
const [myState, setMyState] = useState("1");
const contextValue = {
currentValue: myState,
setCurrentValue: newValue => setMyState(newValue)
};
return (
<MyContext.Provider value={contextValue}>
<MyContext.Consumer>
{e => (
<>
<div onClick={() => e.setCurrentValue("2")}>
Click me to change the value
</div>
{e.currentValue}
</>
)}
</MyContext.Consumer>
</MyContext.Provider>
);
}
CodePudding user response:
You're using e.currentValue
outside of MyContext.Consumer
context which does not have e
, so it's throwing an error that e
is not defined from e.currentValue
.
You can wrap them up together under <MyContext.Consumer>{e => {}}</MyContext.Consumer>
function MyComponent() {
const MyContext = React.createContext();
const [myState, setMyState] = React.useState("1");
const contextValue = {
currentValue: myState,
setCurrentValue: (newValue) => setMyState(newValue),
};
return (
<MyContext.Provider value={contextValue}>
<MyContext.Consumer>
{(e) => (
<div>
<div onClick={() => e.setCurrentValue("2")}>
Click me to change the value
</div>
<div>{e.currentValue}</div>
</div>
)}
</MyContext.Consumer>
</MyContext.Provider>
);
}
ReactDOM.render(<MyComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>