UseContext can't find variable? - reactjs

I'm trying to understand useContext but I don't see what I'm doing wrong here, I get the error message "Can't find variable: Test" but in the tutorial I'm reading from it never says anything about needing to import/export other than what is in the code?
Thank you!
App.js
import React, { createContext } from 'react';
const Test = createContext()
export default function App() {
return (
<Test.Provider value="hello">
<Home/>
</Test.Provider> );
}
Home.js
const Home = () => {
return(
<Test.Consumer>
<View style={styles.homeContainer}>
{value}
</View>
</Test.Consumer>
)
}

You aren't exporting Test from App.js, so you can't just implicitly use it in Home.js.
I'd recommend moving it to another file, say, contexts.js:
import React from 'react';
const Test = React.createContext();
export {Test};
You can then do
import {Test} from './contexts';
in both (or all, in the future) of your other source files to refer to the same context type.

I suggest you to create the context in a separate file :
test-context.js
import { createContext } from 'react';
export const TestContext = createContext();
App.js
import React from 'react';
import { TestContext } from './test-context';
export default function App() {
return (
<TestContext.Provider value="hello">
<Home/>
</TestContext.Provider>
);
}
In TestContext.Consumer, you must provide a function to consume the context value.
Home.js
import React from 'react';
import { TestContext } from './test-context';
export default const Home = () => {
return (
<TestContext.Consumer>
value => (
<View style={styles.homeContainer}>
{value}
</View>
)
</TestContext.Consumer>
)
}

We often forget about old school rules, when reading docs about fancy libraries these days.
In your example, Context is just a JS object, in order to access Test.Consumer, Test must be in scope of the file.
So, you have to import Test object (context) on order to access the Consumer property.

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

React Context code not working despite passing proper context

As per the first example at [https://reactjs.org/docs/context.html] the following code should work, but it is not working. Any help? Am I misunderstanding something?
App.js:
import "./App.css";
import React from "react";
import Level1_Child1 from "./Level1_Child1";
import Level1_Child2 from "./Level1_Child2";
export default function App() {
return (
<React.Fragment>
<AppContext.Provider
value={{
String1: "AppContext Passed String1",
String2: "AppContext Passed String2",
}}>
<Level1_Child1 />
<Level1_Child2 />
</AppContext.Provider>
</React.Fragment>
);
}
export const AppContext = React.createContext({
String1: "AppContext Default String1",
String2: "AppContext Default String2",
});
Level1_Child2.js:
import React from "react";
import Level2_Child1 from "./Level2_Child1";
export default function Level1_Child2(Props) {
return (
<React.Fragment>
<h4>H4 element - Level1_Child2 - React.Fragment</h4>
<Level2_Child1 />
</React.Fragment>
);
}
Level2_Child1.js:
import React from "react";
import AppContext from "./App";
export default class Level2_Child1 extends React.Component {
render() {
let aquiredContext = this.context;
return (
<React.Fragment>
<p>
Props passed using context : {aquiredContext.String1}
{aquiredContext.String2}
</p>
</React.Fragment>
);
}
}
Level2_Child1.contextType = AppContext;
The output is as follows :
Level1_Child1 not pasted here as it does not concern us here.
After trying for almost 2 days, I tried the following which successfully resolved my above mentioned issue. Created a seperate .js file for the context object and imported it in the necessary files, which automatically resolved the issue without doing ANY further changes to the code.
AppContext.js:
import React from "react";
let AppContext = React.createContext({
String1: "AppContext Default String1",
String2: "AppContext Default String2",
});
export default AppContext;
Before this, it was showing the following error in the Firefox console:
Redefining it in the AppContext.js separately, resolved the issue. Don't know why, the same code was giving above error when defined in App.js.

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.

useContext(Context) show warning on console in React Native

I have use React Context API hook in react native. I created Consumer and Provider both to pass props and state from parent to child. Code is working perfectly fine, I have received props from parent to child.
I have received following warning on my console:-
Warning: Calling useContext(Context.Consumer) is not supported, may
cause bugs, and will be removed in a future major release. Did you
mean to call useContext(Context) instead?
Please check below added code:-
I have create common context file CommonContext.js.
import React, {createContext} from 'react';
const MyContext = createContext();
export const LoginProvider = MyContext.Provider;
export const LoginConsumer = MyContext.Consumer;
This is my provider code
import React, {PureComponent} from 'react';
import {View, Text} from 'react-native';
import {LoginProvider} from './CommonContext';
export default class Login extends PureComponent {
constructor(props) {
super(props);
}
render() {
return (
<View style={Styles.mainContainer}>
<LoginProvider value={this.props}>
<LoginScreenView />
</LoginProvider>
</View>
);
}
}
From this way i am access parent component data into child hook
import {LoginConsumer} from './CommonContext';
export default function LoginScreenView(props) {
let loginConsumer = useContext(LoginConsumer);
return (
<View style={Styles.mainContainer}>
<Text>{loginConsumer}</Text>
</View>
);
}
You are receiving this error because you are calling useContext on a Context.Consumer instance, instead of a Context.
You do like this:
export const LoginConsumer = MyContext.Consumer;
and then you call useContext on LoginConsumer:
let loginConsumer = useContext(LoginConsumer);
Instead, you should call useContext on MyContext, like this:
Export the context from CommonContext.js:
export const MyContext = createContext();
Import the context instead of the context consumer in the file where you're using it:
import { MyContext } from './CommonContext';
and then using it with useContext:
let login = useContext(MyContext);
So your second component that you posted would look like this:
import { MyContext } from './CommonContext';
export default function LoginScreenView(props) {
let login = useContext(MyContext);
return (
<View style={Styles.mainContainer}>
<Text>{login}</Text>
</View>
);
}

Resources