Reputation: 135
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;
Upvotes: 3
Views: 8457
Reputation: 7801
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 provide an array instead:
<UserContext.Provider value={[value, setValue]}>
Upvotes: 6
Reputation: 87
There are a few issues I see with the React code that I myself struggled with while learning React.
Your button in Buy.js
has a class='buy'
property. Rename that to className='buy'
because that's just React's syntax.
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.
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.
Upvotes: 3
Reputation: 615
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.
Upvotes: 2