React js context returns undefined - reactjs

I want to pass some data to all of my react components for that I have created a context called GlobalContex that wraps all the components. Now this GlobalContex takes data into its prop from MainComponent.
When I console.log this data inside GlobalContext I can see the data in the browser's console but when I consume this data in one of the GlobalContext child component and console, it returns undefined.
Here is my code
MainComponent.js
import React from 'react';
import Header from "./Header";
import Sidebar from "./Sidebar";
import {
Route,
BrowserRouter
} from "react-router-dom";
import UserIndex from "../user/UserIndex";
import TrackerIndex from "../tracker/TrackerIndex";
import AuthUserContextProvider from '../../contexts/AuthUserContext';
import GlobalContextProvider from "../../contexts/GlobalContext";
const MainComponent = (props) => {
const global_data = JSON.parse(props.testProp);
return (
<BrowserRouter>
<div id="wrapper" className="menu-displayed">
<GlobalContextProvider global_data={global_data}>
<div className="prd-container">
<Header/>
<div className="content">
<Route path="/users" component={UserIndex}/>
<Route path="/tracker" component={TrackerIndex}/>
</div>
</div>
<Sidebar/>
</GlobalContextProvider>
</div>
</BrowserRouter>
);
};
export default MainComponent
GlobalContext.js
import React, {createContext, useState, useEffect} from 'react'
export const GlobalContext = createContext();
const GlobalContextProvider = (props) => {
const [context_global_data, setGlobalData] = useState([]);
useEffect(() => {
setGlobalData(props.global_data)
},[])
console.log(context_global_data);
return (
<GlobalContext.Provider value={{context_global_data}}>
{props.children}
</GlobalContext.Provider>
)
}
export default GlobalContextProvider
Console From Global Context
{auth_user: {…}, login_url: "http://127.0.0.1:8000/login", logout_url: "http://127.0.0.1:8000/logout"}
auth_user: {id: 1, name: "Dust Value", email: "dustvalue#dustvalue.com", profile_pic: "dummy.jpg", email_verified_at: null, …}
login_url: "http://127.0.0.1:8000/login"
logout_url: "http://127.0.0.1:8000/logout"
Sidebar.js
import React, {useContext, useState, useEffect} from 'react';
import {NavLink, Link} from 'react-router-dom';
import GlobalContext from "../../contexts/GlobalContext";
const Sidebar = (props) => {
const global_data = useContext(GlobalContext);
useEffect(() => {
console.log(global_data);
})
return (
<div>
Sidebar
</div>
)
export default Sidebar

Related

React error- Uncaught TypeError: Cannot destructure property 'children' of '_ref' as it is undefined

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";

How to pass context value on click one sibling to another sibling component in react

when i click about link from home page component b context value not update with new value, but when click second time after page redirect to about page then it's update with new value.
Context.js
Initialize context api
import React,{createContext} from 'react'
const Context = createContext()
export default Context
layout.js
import Footer from './Footer'
import '../styles/style.scss'
export default function Layout({children}) {
const [context, setContext] = useState("old context value");
console.log(`layout ${context}`)
return (
<Context.Provider value={[context, setContext]}>
<main className='layout'>
<Helmet>
<title>Website Title</title>
</Helmet>
<Header/>
{children}
<Footer/>
</main>
</Context.Provider>
)
}
Header.js
update context with on click
import React,{useContext} from 'react'
import Context from './Context'
import {Link} from "gatsby"
const Header = () => {
const [context, setContext] = useContext(Context);
const onClickHandler = ()=>{
setContext("New context value")
console.log(`footer ${context}`)
}
return (
<div className="header">
<nav className='links'>
<ul>
<Link to="/">Home</Link>
<Link to="/about" onClick={onClickHandler} style={{color:"red"}}>About
onClick</Link>
<Link to="/projects">Project Portfolio</Link>
</ul>
</nav>
</div>
)
}
export default Header
About page
call component b from about page
import React from 'react'
import Layout from '../components/Layout'
import ComponentB from '../components/ComponentB'
export default function About() {
return (
<Layout>
<div>About</div>
<ComponentB/>
</Layout>
)
}
Component b
context consumer component
import React,{useContext} from 'react'
import Context from './Context'
import {Link, useStaticQuery, graphql } from "gatsby"
const ComponentB = () => {
const [context, setContext] = useContext(Context);
console.log(`component b ${context}`)
return (
<div className="component-b">
<h1>component {context}</h1>
</div>
)
}
export default ComponentB
Here is my GitHub Code url

React JS context with useState

I'm creating a simple example in react js using createContext and useState, but I'm doing something wrong, look it:
this is my component categoriacontex.js
import { createContext } from "react";
const CategoriaContext = createContext();
export default CategoriaContext;
this's component types.js
export const GET_CATEGORIAS = "GET_CATEGORIAS";
this's component categoriasreducer.js
import { GET_CATEGORIAS } from "../types";
export default (state, action) => {
const { payload, type } = action;
;
switch (type) {
case GET_CATEGORIAS:
return {
...state,
categorias: payload,
};
default:
return state;
}
};
this's component categoriastate.js
import React, { useState } from 'react';
import CategoriaContext from './CategoriaContext';
import CategoriaReducer from './CategoriasReducer';
import Data from '../../Data/Categorias.json';
import { GET_CATEGORIAS } from "../types";
const CategoriaState = (props) => {
const initialState = {
categorias: [],
selectedCategoria: null,
};
const [state, setstate] = useState(CategoriaReducer, initialState);
const GetCategorias = () => {
try {
setstate({ type: GET_CATEGORIAS, payload: Data });
} catch (error) {
console.error(error);
}
};
return(
<CategoriaContext.Provider
value={{
categorias: state.categorias
}}
>
{props.children}
</CategoriaContext.Provider>
)
};
export default CategoriaState;
this one is component app.js
import React, { Component } from 'react';
import './App.css';
import Header from './Component/Header/Header';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import CategoriaState from './Context/Categorias/CategoriaState';
import AddCat from './Component/Categorias/AddCat';
import Allcat from './Component/Categorias/AllCat';
class App extends Component {
render(){
return(
<CategoriaState>
<div className="container">
<Router>
<Header />
<Switch>
<Route exact path="/">
<h1>home</h1>
</Route>
<Route path="/addcat">
<AddCat />
</Route>
<Route path="/allcat">
<Allcat />
</Route>
</Switch>
</Router>
</div>
</CategoriaState>
)
}
}
export default App;
and this's componente allcat.js
import React, { useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { useContext } from 'react';
import CategoriaContext from '../../Context/Categorias/CategoriaContext';
const AllCat = () => {
const { categorias, GetCategorias } = useContext( CategoriaContext );
useEffect(() => {
GetCategorias();
},[])
return(
<div className="container mx-auto">
<div className="card col-md-5 mx-auto">
<h4 className="card-title text-center px-0 mx-0 border-bottom">Categorias</h4>
<div className="card-body px-0">
</div>
</div>
</div>
)
};
export default AllCat;
I know that I have some errors, because this is my first example using context in react js, I wan't is create a simple crud using context and hook, I have a file data, this file is call Data, this file have an id, description, idfather.
so please, do you can help me, the better way to work with context and usestate??
In categoriastate.js you don't set the GetCategorias member of the Provider's value, so you will only access the categorias from useContext( CategoriaContext ) and the GetCategorias will be undefined (in allcat.js).

Not dispatching an action on Routing in react

I have a component called OneUser , i have input field and button , on clicking that button i will fetch the new title from API and route to new page ,title will be shown in that component called Display.
What is happening now is , on clicking of submit button , routing is happening , but API call is not working .
Please suggest the appropriate answer for me
State logic is working fine , so i didnt posted here.
App.js
import React from 'react';
import './App.css';
import OneUser from './Components/OneUser';
import Display from './Components/Display';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import store from './store'
import {Provider} from 'react-redux'
function App() {
const isAuthenticated = true
return (
<Provider store={store}>
<Router>
<div className="App">
<Switch>
<Route path='/' exact component={OneUser}/>
<Route path='/post' exact component={Display}/>
</Switch>
</div>
</Router>
</Provider>
);
}
export default App;
OneUser.js
import React , {useState, useEffect} from 'react'
import {oneFetchData} from '../redux/oneAction'
import {connect} from 'react-redux'
function OneUser({user,oneFetchData, history}) {
const [id,setId] = useState(1)
const [IdFromButton,setIdFromButton] = useState(1)
const submit = () => {
setIdFromButton(id);
history.push("/post")
}
useEffect( () =>{
oneFetchData(id)
},[IdFromButton]
)
return(
<div>
<input type="text" value={id} onChange={e=> setId(e.target.value)}>
</input>
< button onClick={submit}>Fetch Post</button>
</div>
)
}
const gettingValue = state => {
return{
user: state.data
}
}
const callingAction = dispatch => {
return{
oneFetchData: (id)=>
dispatch(oneFetchData(id))
console.log('dispatched') // not dispatching here function
}
}
Display.js
import React from 'react'
import {useSelector} from 'react-redux'
function Display({history}) {
const user = useSelector( state => state.data)
return (
<div>
<h1>
Title from another component - {user.title}
</h1>
</div>
)
}
export default Display
I think your component may be unmounted before the state changes. To fix that, you should call history.push after IdFromButton has changed.
const [id,setId] = useState(1)
const [IdFromButton,setIdFromButton] = useState(1)
const submit = () => {
setIdFromButton(id);
}
useEffect( () =>{
oneFetchData(id)
history.push("/post")
},[IdFromButton]
)

useContext always undefined

Why is useContext undefined?
Context
import React from 'react'
const PathContext = React.createContext()
export default PathContext
from a jsx file
import PathContext from '../../../contexts/pathContext';
.......
<PathContext.Provider
value={{
paths,
pathChecks
}}
>
<MyComponent />
</PathContext.Provider>
In MyComponent.jsx render function..
import PathContext from 'path/to/file';
import {useContext} from 'react';
const {
paths,
pathChecks
} = useContext(PathContext);
UNDEFINED!
What is my context undefined?
Use it like so:
App.js (or Main Component)
// App.js
import React from "react";
import MyContext from "./PathContext";
import MyComponent from "./MyComponent";
export default function App() {
return (
<div className="App">
<MyContext>
<MyComponent />
</MyContext>
</div>
);
}
PathContext.js
// PathContext.js
import React, { createContext } from "react";
export const PathContext = createContext(); // regular export
// A new component that will hold the context values and will wrap your <MyComponent>
const MyContext = ({ children }) => {
const paths = "define your paths";
const pathChecks = "define your pathChecks";
return (
<PathContext.Provider
value={{
paths,
pathChecks
}}
>
{children} // Pass children props
</PathContext.Provider>
);
};
export default MyContext; // default export MyContext component
MyComponent.js (context consumer)
// MyComponent.js
import React, { useContext } from "react";
import { PathContext } from "./PathContext";
const MyComponent = () => {
const { paths, pathChecks } = useContext(PathContext);
return (
<div>
<div>{paths} value</div>
<div>{pathChecks} value</div>
</div>
);
};
export default MyComponent;
Here is a sandbox example.
I think you need to use {useContext} from 'react' instead of {useContext} from React
Please check this example. It is working fine.
import React, {useContext, useEffect, useReducer, useState} from 'react';
import PathContext from "./PathContext";
function PathContextExample() {
const paths = 'this is path';
const pathChecks = 'this is path checks';
return (
<div>
<PathContext.Provider
value={{
paths,
pathChecks
}}
>
<MyComponent/>
</PathContext.Provider>
</div>
)
}
export default PathContextExample;
function MyComponent() {
const {
paths,
pathChecks
} = useContext(PathContext);
return (
<div>
{paths}
<br/>
{pathChecks}
</div>
)
}
In MyComponent.jsx file you should import PathContext

Resources