xxxxxxxxxx
//# Contect.js
import { useEffect, useState, createContext } from "react";
export const CharityContext = createContext();
export const CharityContextProvider = ({ children }) => {
const loki = "chaulagain";
return <CharityContext.Provider value={{ loki }}>{children}</CharityContext.Provider>;
};
//# app.js
import { CharityContextProvider } from "../context/Context";
function MyApp({ Component, pageProps }: AppProps) {
return (
<CharityContextProvider>
<Component {pageProps} />
</CharityContextProvider>
);
}
export default MyApp;
//# fetch data in any file
import React, { useContext } from "react";
import { CharityContext } from "../context/Context";
function Index() {
const { loki } = useContext(CharityContext);
console.log(loki); //-->Result:Chaulagain
return <div>Index</div>;
}
export default Index;
xxxxxxxxxx
import React, { useContext } from "react";
import CountContext from "./context";
const Child = () => {
const context = useContext(CountContext);
const { countHandler } = context;
return (
<div>
<button onClick={countHandler}>Increment</button>
</div>
);
};
export default Child;
xxxxxxxxxx
const UserProvider = ({ children }) => {
const [name, setName] = useState("John Doe");
const [age, setAge] = useState(1);
const happyBirthday = () => setAge(age + 1);
return (
<UserContext.Provider value={{ name, age, happyBirthday }}>
{children}
</UserContext.Provider>
);
};
xxxxxxxxxx
/*
Context is a feature of React that allows us to create a piece of
state that any component within an area of your
application can subscribe to.
------------- Why prop drilling is not ideal?----------
When props only have to be drilled through 1-2 components,
prop drilling is a good strategy for making data available.
However, when there are more layers to drill through, there may
end up being many components that take in drilled props and pass
down those props without ever using them.
This can be a negative for two reasons:
1) It bloats your code and makes it harder to understand or
use the middle components.
2) It causes middle components to re-render for changes
to drilled props even if they don’t use those props themselves.
*/
/*
How do we use React Context API?
Create a new file then we start by creating a React context object,
a named object created by the React.createContext() function. you
can import from react at the top.
*/
export const MyContext = createContext();
/*
Context objects include a .Provider property that is a
React component. It takes in a 'value' prop to be stored in the context.
*/
<MyContext.Provider value="Hello world!">
<ChildComponent />
</MyContext.Provider>
/*
That 'value' is available to all its
descendent components (ChildComponet).
-----How ChildComponent can retrieve the context's value?-----
ChildComponent — can then retrieve the context’s value with
React’s useContext() hook.
*/
import { useContext } from 'react';
import { MyContext } from './MyContext.js'
const ChildComponent = () => {
const value = useContext(MyContext);
return <p>{value}</p>;
}
// Renders <p>Hello, world!</p>
/*
The useContext() hook accepts the context object as an
argument and returns the current value of the context.
Rejoice — prop drilling that value is no longer needed!
*/
/*
---------What if we want to reuse the same context multiple times
with different values????----------
Answer: A .Provider component may be reused with the same
context multiple times in an application with different values.
For example, a component might render two .Provider
components that each receive a different value:
*/
const GreetingContext = React.createContext();
const ChildComponent = () => {
const greeting = useContext(GreetingContext);
return <h2>{greeting}</h2>
}
const MyComponent = () => {
return (
<>
<GreetingContext.Provider value="bonjour le monde!">
<ChildComponent />
</GreetingContext.Provider>
<GreetingContext.Provider value="hallo welt!">
<ChildComponent />
</GreetingContext.Provider>
</>
);
};
/*
----------- .Provider Wrappers -------------------
It’s common coding pattern for React applications to
create a “wrapper” component around a .Provider component.
The wrapper component can provide a value of its choosing,
often one of its props or a string literal,
to the .Provider component.
*/
const ThemeContext = React.createContext();
const ThemedMessage = ({ children, theme }) => { //takes two props children and theme
return (
<ThemeContext.Provider value={theme}>
This content is in {theme} mode!
{children}
</ThemeContext.Provider>
);
};
/*
Wrapper components like ThemedMessage can then be used in
place of a .Provider component to wrap children, means replace any
calls to ContextName.Provider with this wrapper component.
*/
const MyComponent = () => {
return (
<ThemedMessage theme="dark"> // *Important*
/*
Make sure to use the *theme* prop rather than the
*value* prop of the .Provider.
*/
Hooray!
</ThemedMessage>
)
};
/*
---------Updating Context----------------------
Now we have setup a wrapper component around a Context .Provider
component. Now we’re going to make use of that wrapper
component by working with React state.
*/
/*
------prop drilling method------
*/
const CounterApp = () => {
const [count, setCount] = useState(0);
return (
<Counter count={count} setCount={setCount} />
);
};
/*
-------React Context method-------
One common pattern is to have the context provide an object
containing both of those values. Child components that
consume the context can then use both (or either of)
the state and the state updater function.
*/
const CounterContext = React.createContext();
const CounterArea = ({ children, numProp }) => {
const [count, setCount] = useState(numProp);
return (
<CounterContext.Provider value={{ count, setCount }}>
{children}
</CounterContext.Provider>
);
};
const Counter = () => {
// destructuring to use those values from the object
// returned by useContext().
const { count, setCount } = useContext(CounterContext);
return (
<button onClick={() => setCount(count => count+1)}>
{count}
</button>
);
};
const CounterApp = () => {
return (
<CounterArea>
<Counter />
</CounterArea>
)
}
xxxxxxxxxx
const withUser = (Child) => (props) => (
<UserContext.Consumer>
{(context) => <Child {props} {context} />}
{/* Another option is: {context => <Child {...props} context={context}/>}*/}
</UserContext.Consumer>
);
xxxxxxxxxx
import React, { createContext } from "react";
const UserContext = createContext();
xxxxxxxxxx
ReactDOM.render(
<UserProvider>
<App />
</UserProvider>,
document.getElementById("root")
);