React context provider does not show defaults - reactjs

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.

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

UseContext can't find variable?

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.

useContext hook returns undefined

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

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.

The component for route must be a React component

The component for route 'Feed' must be a React component.
I've checked most of the other similar questions here but the majority of them are due to basic syntax (which maybe I have too but am blind to!). I've removed chunks of code that aren't relevant to this issue (navigationOptions and other screens) and can still reproduce the error with just the below:
./navigators/AppNavigator.js
import { createStackNavigator, createAppContainer, createBottomTabNavigator } from 'react-navigation';
import { FeedScreen } from '../screens/FeedScreen';
const FeedStack = createStackNavigator({
Feed: FeedScreen,
});
const DashboardTabNavigator = createBottomTabNavigator(
{
FeedStack
}
);
const DashboardStackNavigator = createStackNavigator(
{
DashboardTabNavigator: DashboardTabNavigator
}
);
const AppContainer = createAppContainer(DashboardStackNavigator);
export default AppContainer;
./screens/DashboardScreen.js
import React, { Component } from 'react';
import { StyleSheet } from 'react-native';
import AppContainer from '../navigators/AppNavigator';
class DashboardScreen extends Component {
render() {
return (
<AppContainer />
);
}
}
export default DashboardScreen;
./screens/FeedScreen.js
import React from 'react';
import { View } from 'react-native';
export default class FeedScreen extends React.Component {
render() {
return (
<View>
</View>);
}
}
Any idea what I've done wrong here?
You have a default export for FeedScreen ... not a named export:
Try this:
import FeedScreen from '../screens/FeedScreen';
import { FeedScreen } from '../screens/FeedScreen'
You cannot importe like this if you re exporting by default.
Remove your default export or do replace your importe like this :
import FeedScreen from '../screens/FeedScreen'
You are using export default statement, that means you canĀ“t import like that, you should provide a variable to store the component.
import Component from 'defaultexport'

Resources