Shortly, when I try to use useState with useContext in one of my components, all pages just disappear. UseState in some reason block my Routers and I have no idea why... Can you tell me where is my mistake?
Some code below: Index.js
export default function App() {
const [value, setValue] = useState(false) -----> here I set the state
return (
<BrowserRouter>
<UserContext.Provider value={{ value, setValue }}>
<Routes>
<Route path='/' element={<Layout />}>
<Route index element={<Home />} />
<Route path='Home' element={<Home />} />
<Route path='Menu' element={<Menu />} />
<Route path='Story' element={<Story />} />
<Route path='Coffee' element={<Coffee />} />
<Route path='Cart' element={<Cart />} />
</Route>
</Routes>
</UserContext.Provider>
</BrowserRouter>
)
}
// ReactDOM.render(<App />, document.getElementById("root"))
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<App />)
Buy.js component
import { useState } from "react"
import { useContext } from "react"
import { UserContext } from "../../UserContext"
const Buy = () => {
const [buttonText, setButtonText] = useState("Add to cart")
const [isActive, setIsActive] = useState(false)
// const [value, setValue] = useContext(UserContext) --> after I declare state everything disappears
const addToCart = () => {
setIsActive((current) => !current)
// setValue(true)
if (isActive) {
setButtonText("Add to cart")
}
}
return (
<div>
<button
class='buy'
style={{
fontSize: isActive ? "0.8rem" : "1rem",
color: isActive ? "lightgray" : "white",
}}
onClick={() => {
addToCart()
}}
>
{buttonText}
</button>
</div>
)
}
export default Buy
UserContext.js
import { createContext } from "react"
export const UserContext = createContext(null)
Actually, I need this Context only for routes "Coffee" and "Cart", but if I wrap only this 2 routes will be the same problem and all is disappear. Should I maybe use Context in my Layout.jsx instead of Index.js? Thank you.
const Layout = () => {
return (
<>
<Navbar />
<Outlet />
<Footer/>
</>
);
};
export default Layout;
CodePudding user response:
Your context provides an object, not an array, so you should destructure using curly braces when you use it:
const { value, setValue } = useContext(UserContext);
Or if you want to keep this way of destructuring, you can return an array instead:
<UserContext.Provider value={[value, setValue]}>
CodePudding user response:
First i cannot see your Buy.js component between Context.Provider tree.
Then please try to use as object to destruct state values, not array.
CodePudding user response:
There are a few issues I see with the React code that I myself struggled with while learning React.
Issue #1
Your button in Buy.js
has a class='buy'
property. Rename that to className='buy'
because that's just React's syntax.
Issue #2
Your button's onClick={}
property should reference only the function's name, and should not call the function itself. Change the onClick
to onClick={addToCart}
. Do not add the anonymous arrow function, simply input the name of the function.
Possible Issue #3
Most of the conditional functionality you are looking for can be implemented with React's useEffect()
hook. Change addToCart()
in the following way:
const addToCart = () => {
setIsActive();
}
useEffect(() => {
if(isActive) {
setButtonText("Add to cart");
}
}, [isActive]);
Make sure to import useEffect() before using this.