useContext hook returns undefined - reactjs

Inside of App component I have Component1 which has a nested component. I create a contextApi with React.createContext() to use it inside of nested component . Using useContext() hook I am trying to get myname value from App.js and use it as style, but it returns undefined.
App component
import logo from './logo.svg';
import './App.css';
import Component1 from '../src/Component1/Component1'
import React from 'react'
export const Theme = React.createContext();
function App() {
const myname = {
width:'100px',
height:'100px',
background:'red'
}
return (
<Theme.Provider value={{myname}}>
<Component1>
</Component1>
</Theme.Provider>
);
}
export default App;
Component1
import NestedComponent from '../NestedComponent/NestedComponent'
function Component1 (){
return <NestedComponent></NestedComponent>
}
export default Component1
NestedComponent
import Theme from '../App'
import {useContext} from 'react'
export default function NestedComponent(){
const mystyle = useContext(Theme) //returns undefined
return <div style = {mystyle}> </div>
}

Inside Theme.Provider do this:
<Theme.Provider value={myname}>
It will work.
Check here

Related

useContext is returning returning the initial value and not the assigned value?

This is my first time using usecontext,and i got stuck with this problem,where the usecontext returns the initial value and not the passed value.
This is my App.js
import { useContext } from 'react';
import {userprop} from './Context'
function App() {
const value = useContext(userprop)
console.log(value)
return (
<div >
</div>
);
}
export default App;
This is my Context.js
import React, { useState ,createContext} from 'react'
import App from './App'
export const userprop =createContext(0)
function Context(){
const [a,seta] = useState(2)
return(
<userprop.Provider value={3}>
<App/>
</userprop.Provider>
)
}
export default Context;
Iam getting the output as 0 and not 2 !!
How can i solve it?
You are approaching it the wrong way. The Context Provider should wrap everything that wants to consume the context.
Making minimal changes to your code :
import { useContext } from "react";
import { userprop } from "./Context";
function App() {
const value = useContext(userprop);
console.log(value);
return <div></div>;
}
export default App;
Also, you are not passing the state value into the context, but instead a hard coded number 3. So that needs change too:
import React, { useState, createContext } from "react";
import App from "./App";
export const userprop = createContext(0);
function Context() {
const [a, seta] = useState(2);
return (
<userprop.Provider value={a}>
<App />
</userprop.Provider>
);
}
export default Context;
Now, you have to mount Context as your main component into the div instead of App though.
Link

Error: Element type is invalid: expected a string (for built-in components)

Check the render method of App.
I am trying to use Context Api I have App component and it returns Component1 which has nested component .I thought since I wrap Component1 inside of ContextApi.Provider ,all it's nested components should see value passed as a prop to the contextApi. I am getting the same error every time I wrap element inside of ContextApi.
Here is the App Component:
import logo from './logo.svg';
import './App.css';
import Component1 from '../src/Component1/Component1'
import ContextApi from '../src/context-api'
function App() {
return (
<ContextApi.Provider value={{
name :"PARVIZ PIRIZADA"
}}>
<Component1></Component1>
</ContextApi.Provider>
);
}
export default App;
Here is the Component1
import NestedComponent from '../NestedComponent/NestedComponent'
function Component1 (){
return <NestedComponent></NestedComponent> //nested component inside of Component1
}
export default Component1
Here is the NestedComponent
import ContextApi from '../context-api'
export default function NestedComponent(){
return <ContextApi.Consumer> // here I am trying to get value in contextApi as an consumer
{(ctx)=>{
return <div> {ctx.name}</div>
}}
</ContextApi.Consumer>
}
Here is my ContextApi
import React from 'react'
export default function Context(){
return React.createContext({
name : "PARVIZ"
})
}

React context provider does not show defaults

I am trying to keep things organized with my project. So I created a config folder in which I placed a context folder. Inside the context folder I want to handle all things context.
So I have index.ts which is as follows:
import { ThemeContextProvider } from './context';
export default ThemeContextProvider;
And a context.tsx file with the following:
import { createContext } from 'react';
export const ThemeContext = createContext({});
export const ThemeContextProvider = ThemeContext.Provider;
In my app.tsx I have
import React from 'react';
import ThemeContextProvider from './config/context';
import theme from './theme';
export default function App() {
return (
<ThemeContextProvider value={theme}>
...
</ThemeContextProvider>
);
}
The above works. But I want to move the theme into context.tsx and load it there as default so I keep my App.tsx as clean as possible
So in context.tsx I change to:
import { createContext } from 'react';
import theme from '../../theme';
export const ThemeContext = createContext(theme);
export const ThemeContextProvider = ThemeContext.Provider;
And in App.tsx I change <ThemeContextProvider value={theme}> to <ThemeContextProvider>
React immediately complains about <ThemeContextProvider> and wants the value prop. When I pass value={} and try to get default values from the context, they are no longer there.
Any ideas what's going on and advise about how to handle it, and also advise about best practices? Perhaps I'm going at it incorrectly?
You can create another component that wraps the content and passes the theme to the context provider
import { createContext } from 'react';
import theme from '../../theme';
export const ThemeContext = createContext({});
export const ThemeContextProvider = ThemeContext.Provider;
export const YourContextProvider = ({ children }) => (
<ThemeContextProvider value={theme}>
{children}
</ThemeContextProvider>;
);
and then use it in the app component
import React from 'react';
import YourContextProvider from './config/context';
export default function App() {
return (
<YourContextProvider>
...
</YourContextProvider>
);
}
You can still name the YourContextProvider as ThemeContextProvider if you want but I'd recommend not. It may be hard to follow for the future maintenance.

warning : is defined but never used

I created a jsxUses.js file in the components folder, but when I import it in App.js its shows warning: 'jsxUses' is defined but never used
//This is App.js file
import React, { Component } from 'react';
import './App.css';
import jsxuses from './components/jsxUses';
class App extends Component{
render() {
return (
<div className="App">
<jsxuses/>
</div>
);
}
}
export default App;
and this is jsxUses.js file
import React from 'react'
const jsxuses = () => {
return (
<div>
<h1> Hey there!</h1>
</div>
);
}
export default jsxuses;
React Element should be PascalCased. So it should be
import JsxUses from './components/jsxUses';
...
<JsxUses />
Change your jsxUses.js as:
...
const JsxUses = () => {
...
export default JsxUses;
And your App.js as:
import JsxUses from './components/jsxUses';
...
<JsxUses />
React file structure naming is unopinionated but React elements should be PascalCase for React to know whether or not you're using a function, class or an HTMLelementPascalCased.
Look for more here: Is there an official style guide or naming convention for React based projects?
Hope this helps!
Actually you should avoid using small latter for custom tags.
so you should do
const JsxUses = () => {
...
}
export default JsxUses
and
import JsxUses from './components/jsxUses';
or if you want to write like -
const jsxuses = () => {
...
}
export default jsxuses
then you should import it like
import { default as JsxUses } from './components/jsxUses'
Well, Use import JsxUses from './components/JsxUses'; React component name should be PascalCase.

Why am I getting "useContext is not a function" or "context is not defined"?

I am trying to use context in my stateless component. I updated my react to v16.8.0 and added useContext, however, I keep getting these two errors and don't know what else to do. Here is my code:
import React, { useState } from "react";
import axios from "axios";
import { LanguageContext } from "./languageContext";
import { useContext } from "react";
function StripeButton() {
const context = useContext(LanguageContext);
const stripe = Stripe("pk_live_5PjwBk9dSdW7htTKHQ3HKrTd");
const [error, setError] = useState();
const handleClick = () => {
stripe
.redirectToCheckout({
...
});
};
return (
<div>
<button
id="UrgentCheckedButtonYES"
className="btn-primary"
onClick={handleClick}
>
{this.context.main.name}
<br />
</button>
<div>{error}</div>
</div>
);
}
export default StripeButton;
StripeButton.contextType = LanguageContext;
You need to import useContext like this:
import { useContext } from 'react';
const { useContext } = React
useContext is exported as method property of React
(Tested this in React 18.)
In App.js File:
import { createContext } from "react";
import ChildComponent from "./components/ChildComponent";
export const Context = createContext("Default Value");
export default function App() {
const value = "My Context Value";
return (
<Context.Provider value={value}>
<ChildComponent />
</Context.Provider>
);
}
In ChildComponent.jsx file:
import { useContext } from "react";
import { Context } from "../App";
function ChildComponent() {
const value = useContext(Context);
return <h1>{value}</h1>;
}
export default ChildComponent;
You can have as many consumers as you want for a single context. If the context value changes,then all consumers are immediately notified and re-rendered.
If the consumer isn't wrapped inside the provider, but still tries to access the context value (using useContext(Context) or <Context.Consumer>), then the value of the context would be the default value argument supplied to createContext(defaultValue) factory function that had created the context.

Resources