I have just started learning useContext hook and I am struck in this problem.
I am not able use the hook itself when I am trying to print that in console its says undefined.
This is the App.js
import "./styles.css";
import NoteState from "./Context/Notes/NoteState";
import About from "./components/About";
export default function App() {
return (
<>
<About />
<div>ankit</div>
<NoteState>
<About />
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
</NoteState>
</>
);
}
These are the files where the hook is defined
import { createContext } from "react";
const noteContext = createContext();
export default noteContext;
Second one is
import React from "react";
import NoteContext from "./NoteContext";
const NoteState = (props) => {
const state = {
name: "Name",
surname: "Surname"
};
return (
<>
<NoteContext.Provider value={state}>
{props.childern}
</NoteContext.Provider>
</>
);
};
export default NoteState;
I am trying to use this in About.jsx
import React from "react";
import noteContext from "../Context/Notes/NoteContext";
import { useContext } from "react";
const About = () => {
const a = useContext(noteContext);
console.log(a); - >> comes undefined
return (
<>
{/* <div>this is about note me but {a.name}</div> */} this gives error
</>
);
};
export default About;
You can see the same in this codesand box link.
link
There seems to be a typo in your NoteState component. It should be props.children and not childern. When I made that change and ran your sandbox, it was working fine.
Try to wrap the all application into NoteContext:
import NoteContext from './NoteContext';
export default function App() {
return (
<>
<NoteContext.Provider value={state}>
<About />
<div>ankit</div>
<NoteState>
<About />
<div className='App'>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
</NoteState>
</NoteContext.Provider>
</>
);
}
Related
I am having a problem that the value made by one component cannot be delivered to another component. I made a state in the top component and I think I connected it well. But the desired array made of state is empty. Sorry for the long code to ask.
The code below is the top component, and InCart is the state that I'm having issues with.
App.js:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Site from './Site/Site';
import { useState } from 'react';
import RealCart from './RealCart/RealCart';
function App() {
const [Inproducts,setInproducts] = useState([])
const [InCart, setInCart] = useState([]);
return (
<BrowserRouter>
<Routes>
<Route path='/realCart' element={<RealCart InCart={InCart} setInCart={setInCart}/>} />
<Route path='/loginHome' element={<Site InCart={InCart} setInCart={setInCart} Inproducts={Inproducts} setInproducts={setInproducts}/>}/>
</Routes>
</BrowserRouter>
);
}
export default App;
There are many components connected in the middle, so I omitted it, but the props are connected as well. And I got the json file from here.
Section5Bottom.jsx:
import axios from 'axios';
import React, { useEffect } from 'react';
import "../section5.css";
import Section5Card from './Section5Card';
function Section5Bottom({Inproducts, setInproducts, InCart, setInCart}) {
useEffect (()=> {
axios.get("/data/products.json").then((data)=>{
setInproducts(data.data.products);
});
},[setInproducts]);
return (
<div id='Section5Bottom'>
{
Inproducts.map((product)=>{
return <Section5Card key={`key-${product.id}`} product={product} InCart={InCart} setInCart={setInCart}/>
})
}
</div>
)
}
export default Section5Bottom;
When I clicked the icon below the file, I used the InCart made in App.js to put the array value of the selected card in the array. If I check the console here, the array is good as shown in this photo.
Section5Card.jsx:
import '../section5.css';
import {FaCartPlus} from 'react-icons/fa';
import { useDispatch } from 'react-redux';
import './card.css';
function Section5Card({product, InCart, setInCart}) {
const dispatch = useDispatch();
const handleCart = () => {
const cartItem = {
id : product.id,
image : product.image,
provider : product.provider,
price : product.price,
name : product.name
}
setInCart([...InCart, cartItem])
}
return (
<div>
<div id='CardWrap'>
<div>
<img id='Section5CardImg' src={product.image} />
</div>
//************************************
<div>
<FaCartPlus size='20' style={{color:'black', position:'relative', top:'124px', left:'130px', cursor:'pointer'}} onClick={()=>{dispatch({type:"ADD"}); handleCart()}} />
</div>
//*************************************
<div id='CardBot'>
<div id='CardBotBPrice'>
₩{product.price}
</div>
<div id='CardBotTag'>
{product.people?
<span id='CardBotTagPeople'>
{product.people}명
</span>:
<>
<span id='CardBotTagSale'>
{product.sale}
</span>
</>}
</div>
</div>
</div>
</div>
)
}
export default Section5Card;
And the below file is the one I wish to bring up in the InCart state. But even if I check with the console, the array is empty as shown below:
RealCart.jsx:
import React from 'react'
import Top from '../Site/Header/Top'
import Navi from '../Site/Header/Navi/Navi'
import Cart from './Components/Cart';
import CartHeader from './Components/CartHeader';
function RealCart(InCart, setInCart) {
console.log(InCart)
return (
<div>
<Top />
<Navi />
<Cart />
<CartHeader />
</div>
)
}
export default RealCart;
In your RealCart.jsx file you have to wrap your props with {} and it will be like
function RealCart({InCart, setInCart}) {
console.log(InCart)
return (
<div>
<Top />
<Navi />
<Cart />
<CartHeader />
</div>
)
}
Here is my layout tsx: where I am using outlet.
import { FormRegister } from '#stonehenge/forms';
import { HeaderPublic } from '#stonehenge/header-public';
import { ModalLogin } from '#stonehenge/modals';
import { useState } from 'react';
import { Outlet } from 'react-router-dom';
import { HeaderPublicLinkSchema } from './header-link.schema';
import layoutStyle from './layout-public.module.scss';
export function LayoutPublic() {
const [modalActive, setModalActive] = useState<boolean>(true);
return (
<section className={layoutStyle['app-wrapper']}>
<header className="app-header">
<ModalLogin isModal={modalActive} children={<FormRegister />} />
<HeaderPublic schema={HeaderPublicLinkSchema} />
</header>
<main className="app-main">
<h1>Hi {modalActive}</h1>
<Outlet context={setModalActive} />
</main>
<footer className="app-footer"></footer>
</section>
);
}
export default LayoutPublic;
Here I am trying to use the outlet context but getting above error:
import { Button } from 'antd';
import { Dispatch, SetStateAction } from 'react';
import { useOutletContext } from 'react-router-dom';
import styles from './admin-register.module.scss';
export function AdminRegister() {
const [setModalActive] =
useOutletContext<Dispatch<SetStateAction<boolean>>>();error is here
return (
<div className={styles['container']}>
<h1>Welcome to AdminRegister!</h1>
<Button onClick={() => setModalActive(true)}>Register</Button>
</div>
);
}
export default AdminRegister;
The error:
Type Dispatch<SetStateAction<boolean>> must have a [Symbol.iterator]() method that returns an iterator.ts(2488)
Can anyone help me to understand the issue please?
const [setModalActive] =
You're destructuring this as though you expect useOutletContext to return an array, but it's just returning a function. Change it to:
const setModalActive =
I have used useEffect to fetch API & dispatch an action from inside it to update state. I am using context API, useReducer for state management and also react-router in this project.
In Header.js as soon as i import/use CartState and state variable (e.g. cart.length) then the app breaks down and items from api are not rendered and i get this error. In home.js also i am using state, but with only that part it does not give any error.
Below i am attaching two images, one with error and one where it is rendered when i remove CartState from header.js
Or you can see the codesandbox : https://codesandbox.io/s/serene-fast-297j3h?from-embed=&file=/
Website picture when CartState removed from header.js
Error message - website picture
Please tell me what is the issue here and what should be done.
index.js file:
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import "bootstrap/dist/css/bootstrap.min.css";
import { BrowserRouter } from "react-router-dom";
import GlobalContext from './context/GlobalContext'
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<GlobalContext>
<App />
</GlobalContext>
</BrowserRouter>
</React.StrictMode>
);
App.js:
import "./App.css";
import Header from "./Components/Header";
import { Routes, Route } from "react-router-dom";
import Home from './Components/Home/Home'
import Cart from './Components/Cart'
function App() {
return (
<>
<Header />
<Routes>
<Route path="/" exact element={<Home/>}></Route>
<Route path="/cart" exact element={<Cart/>}></Route>
</Routes>
</>
);
}
export default App;
GlobalContext.js:
const CartContext = createContext();
const GlobalContext = ({children}) => {
const initialState ={
products: [],
cart: []
};
useEffect( ()=>{
const fetchData = async ()=> {
const res = await axios('https://fakestoreapi.com/products');
const resAdd = res.data.map((item)=> ({...item, inStock: faker.helpers.arrayElement([0,2,5,9,20]), fastDelivery: faker.datatype.boolean() }));
dispatch({type: 'API_CALL_SUCCESS', payload: resAdd});
// console.log(initialState);
}
fetchData();
}, [] )
const [state, dispatch] = useReducer(cartReducer, initialState );
console.log(state);
return (
<CartContext.Provider value={{state, dispatch}}>
{children}
</CartContext.Provider>
);
};
export default GlobalContext;
export const CartState = () => {
return useContext(CartContext);
};
Header.js (part of the code)
import CartState from "../context/GlobalContext";
const Header = () => {
const {
state: { cart },
dispatch,
} = CartState();
return (
<Navbar bg="dark" variant="dark" style={{ height: 100 }}>
<Container>
<Navbar.Brand>
<Link to="/">HOME</Link>
</Navbar.Brand>
<FormControl
className="m-auto"
style={{ width: 500 }}
type="text"
placeholder="Search here the product you want"
/>
<Nav>
<Dropdown
// alignRight
>
<Dropdown.Toggle variant="success">
<FaShoppingCart color="white" fontSize="25px" />
<Badge>
{cart.length}
{/* 1 */}
</Badge>
</Dropdown.Toggle>
Home.js:
import { CartState } from '../../context/GlobalContext'
import SingleProduct from '../SingleProduct';
import './styles.css'
import Filters from '../Filter/Filters';
const Home = () => {
const {state: {products}, } = CartState();
console.log(products);
return (
<div className="home">
<Filters />
<div className="productContainer">
{products.map( (item)=>
<SingleProduct prod = {item} key = {item.id} />
)}
</div>
</div>
)
}
export default Home
You need to modify below code line in Header.js file.
Actual:
import CartState from "../context/GlobalContext";
Expected/correct:
import {CartState} from "../context/GlobalContext";
Reason: CartState is not a default export.
In Header.js:
import CartState from '../context/GlobalContext';
this part of your code is wrong because you didn't export default your CartState function so you should import it like:
import {CartState} from "../context/GlobalContext";
I can't find a proper example on how to implement the SliderPicker as a functional component, any suggestions?
import React,{useState} from "react";
import "../Styles/Pixel-editor.scss"
import { HuePicker,SliderPicker } from 'react-color';
function App(){
return(<div className="App"><SliderPicker/> </div>);
}
You need a state with object, which has a hex property. Then you can set it with onChangeComplete property:
const [color, setColor] = React.useState({ hex: "#FFFFFF" });
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<SliderPicker
color={color}
onChangeComplete={(color) => setColor(color)}
/>
</div>
);
https://codesandbox.io/s/polished-resonance-5il68w
CodeSandbox https://codesandbox.io/s/billowing-hill-j5gmy?file=/src/App.js
import React from "react";
import "./App.css";
import Homepage from "./Components/Homepage";
import { Link, Router } from "#reach/router";
import Details from "./Components/Details";
function App() {
return (
<Router>
<Homepage path="/" />
<Details path="/details" />
</Router>
);
}
export default App;
The above is my app.js file , I am trying to navigate to details page using a Link tag in my Homepage component
import React, { Component } from "react";
import styled, { isStyledComponent } from "styled-components";
import Api from "../API/Accounts";
import { Link } from "#reach/router";
const Homepage = () => {
const [State] = Api("https://panorbit.in/api/users.json");
return (
<React.Fragment>
<div className={"container"}>
<div>
<h2>Select an Account</h2>
<div style={{ padding: 0 }}>
{State.map((item) => (
<Link to={"/details"}>
{}
<img src={item.profilepicture} alt="Girl in a jacket"></img>
<span>{item.name}</span>
</Link>
))}
</div>
</div>
</div>
</React.Fragment>
);
};
export default Homepage;
My issues is The details page dont render after navigating to /details page, Only if I refresh the page it renders properly.
Please help me out, beating my head over this one for few days
UPDATE
State is an Object that is returned when i call the API
import react, { useEffect, useState } from "react";
import axios from "axios";
const Api = (Api) => {
const [data, setData] = useState([]);
useEffect(async () => {
const result = await axios(Api).then((x) => setData(x.data.users));
}, []);
return [data];
};
export default Api;
think it should be:
<Details path="details" />
instead of
<Details path="/details" />