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
Related
I am using the following Languageselector in my next project:
import React, { useState } from 'react'
import i18n from '../src/services/i18n'
import Link from 'next/link'
import { useRouter } from 'next/router'
const LanguageSelector = (props) => {
const [language, setLanguage] = useState(i18n.language);
const router = useRouter()
const handleOnclick = (value) => {
router.push(router.asPath, router.asPath, { locale: value });
};
console.log(router);
return (
<>
<div className={props.className!==undefined&&props.className!==""? ('d-inline-block d-xl-none '+props.className):"d-inline-block d-xl-none "} >
<select onChange={(e)=>{handleOnclick(e.target.value)}} required defaultValue={router.locale}>
<option value='de'>Deutsch</option>
<option value='en'>Enligsh</option>
</select>
</div>
<div className="d-none d-xl-block">
{router.locale==="en"? <div><Link href={router.asPath} locale='de'>DE</Link></div> : <div>DE</div>}
<p>|</p>
{router.locale==="de"? <div><Link href={router.asPath} locale='en'>EN</Link></div> : <div>EN</div>}
</div>
</>
)
}
export default LanguageSelector
_app.js
This does work fine until the visitor is on an URL, that has a # parameter. The URL in browser bar still changes but the language stays the same. How can I change the language on URLs with hash?
EDIT: This is how I am using translation
import Layout from '../components/Layout'
import { appWithTranslation } from 'next-i18next';
import React, {useState, useEffect} from 'react';
import { useRouter } from 'next/router'
const app = ({Component, pageProps })=> {
const router = useRouter()
function updateSchnellzugriffe(value, mobileValue){
setSchnellzugriffe(value);
setMobileSchnellzugriffe(mobileValue);
}
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default appWithTranslation(app)
And this is an example of pageComponent
import React, {useEffect, useState} from 'react'
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
const home = (props) => {
const { t } = useTranslation(['common','home']);
return (
<h1 >{t("home:headline")}</h1>
)
};
export async function getStaticProps({ locale }){
return {
props: {
...await serverSideTranslations(locale, ['common','home']),
},
}
}
export default home
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 sure why react context is not using the value passed in provider?
import { createContext } from "react";
const initialState = {
isOpen: false
};
export const alertContext = createContext(initialState);
export default (props) => {
return (
<>
<alertContext.Provider value={{ isOpen: true }}>
{props.children}
</alertContext.Provider>
</>
);
};
import "./styles.css";
import { useContext } from "react";
import AlertProvider, { alertContext } from "./AlertProvider";
export default function App() {
let value = useContext(alertContext);
return (
<div className="App">
<AlertProvider>
<pre>{JSON.stringify(value)}</pre>
</AlertProvider>
</div>
);
}
Why is the value for isOpen not true?
https://codesandbox.io/s/serene-faraday-1oib3?fontsize=14&hidenavigation=1&theme=dark
You need to wrap your provider around App in index.js
as shown:
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import AlertProvider from "./AlertProvider";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<AlertProvider>
<App />
</AlertProvider>
</StrictMode>,
rootElement
);
and your app.js will look like this:
import "./styles.css";
import { useContext } from "react";
import { alertContext } from "./AlertProvider";
export default function App() {
let value = useContext(alertContext);
return (
<div className="App">
<pre>{JSON.stringify(value)}</pre>
</div>
);
}
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
I'm trying to reach a value using React Hook useContext, but keep getting the following error:
TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
CartContext.js
import React, {useState, createContext} from 'react';
export const CartContext = createContext();
export const CartProvider = (props) => {
const [cart, setCart] = useState([]);
return (
<CartContext.Provider value={[cart, setCart]}>
{props.children}
</CartContext.Provider>
)
}
And im trying to reach it from Cart.js
import React, {useContext} from 'react'
import {CartContext} from '../../pages/contact/CartContext';
import { slide as Menu } from 'react-burger-menu'
import './Cart.css'
export default function Cart() {
const [cart, setCart] = useContext(CartContext); //This line causes the error
return (
<div>
<Menu right width={350}
isOpen={false}
id={"testi"} className={ "my-menu" }
customBurgerIcon={<i className="fa fa-shopping-cart" aria-hidden="true"/>}
burgerButtonClassName={ "cartButton" }>
<h1>Hello</h1>
</Menu>
</div>
)
}
It seems alright. See this CodeSandbox:
https://codesandbox.io/s/eager-brattain-2zhxj
index.js
import React from "react";
import ReactDOM from "react-dom";
import Cart from "./Cart";
import { CartProvider } from "./CartContext";
import "./styles.css";
function App() {
return (
<CartProvider>
<Cart />
</CartProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
CartContext.js
import React, { useState, createContext } from "react";
export const CartContext = createContext();
export const CartProvider = props => {
const [cart, setCart] = useState(["a", "b"]);
return (
<CartContext.Provider value={[cart, setCart]}>
{props.children}
</CartContext.Provider>
);
};
Cart.js
import React, { useContext } from "react";
import { CartContext } from "./CartContext";
function Cart() {
const [cart, setCart] = useContext(CartContext);
function updateCart() {
setCart(prevState => {
const newState = Array.from(prevState);
newState.push("c");
return newState;
});
}
return (
<React.Fragment>
<div>I am Cart</div>
<div>Cart value: {JSON.stringify(cart)}</div>
<button onClick={updateCart}>Add 'c' to cart</button>
</React.Fragment>
);
}
export default Cart;