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;
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
src/contexts/user.js
import { createContext, useState } from "react";
export const UserContext= createContext();
export const UserContextProvider= (props)=>{
const [user, setUser] = useState(null);
//const [name, setName] = useState(null);
return (
<UserContext.Provider value={{user: [user, setUser] }}>
{props.children}
</UserContext.Provider>
)
};
src/components/signin-btn/index.js
import React, {useContext} from 'react';
import "./style.css"
import { UserContext } from '../../contexts/user';
import { signInWithGoogle } from '../../services/auth';
import "./style.css";
export default function SignInBtn() {
//const [user, setuser] = useState(SignInBtn) {
const[user,setUser] = useContext(UserContext).user;
const signInBtnClick = async() => {
let userBySignIn = await signInWithGoogle();
if(userBySignIn) setUser(userBySignIn);
};
return (
<div className="signInBtn">
<p>Sign in with Google</p>
</div>
);
}
src/App.js
import React from 'react';
import './App.css';
import {Home} from './pages';
function App() {
return (
<UserContextProvider>
<div className="App">
<Home />
</div>
</UserContextProvider>
);
}
export default App;
Error Failed to compile. src\App.js Line 8:6: 'UserContextProvider' is not defined react/jsx-no-undef
Am I missing something?
App.js is missing the following line:
import { UserContextProvider } from './contexts/user';
I keep getting an error when I try to use Context API for dark/light mode in App.js
Theme.js
import React, { useState } from "react";
export const ThemeContext = React.createContext();
//theme = light, dark
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("dark");
const toggleTheme = () => {
if (theme === "light") setTheme("dark");
else setTheme("light");
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
App.js
import { ThemeContext, ThemeProvider } from "./app/utility/ThemeManager";
export default function App() {
const { theme } = useContext(ThemeContext); // This is throwing the error
return (
<ThemeProvider>
...//Rest of my app
//How I'd like to use my theme
<StatusBar style={theme === "dark" ? "light" : "dark"} />
</ThemProvider>
);
};
I'd like to understand why this is throwing the error and how I could fix it?
Thanks in advance!
Import ThemeProvider in index.js
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { ThemeProvider } from "./Theme.js";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<ThemeProvider>
<App />
</ThemeProvider>,
rootElement
);
and in App.js
import {ThemeContext} from "./Theme.js"
import StatusBar from './StatusBar';
import {useContext} from 'react'
export default function App() {
const { theme } = useContext(ThemeContext);
return (
<>
..... Rest Of your Code
</>
);
};
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>
);
}
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