If React Context API is meant to be used for passing global variables around, why should we use them to substitute passing props from parent to child components (prop drilling)? Since most props being passed are not meant to be available application-wide i.e globally.
3 Answers
The new react context api allows you to "scope" the values, you don't have to wrap your whole application with the context provider, you can only wrap the part of the component tree where you need particular props. It can be useful when your component tree is deeply nested and you'd need to pass certain props multiple levels.

- 328
- 1
- 2
- 12
The variables or values defined in context are available to any component that tries to destructure those values. However, if you have any setters that change those defined values, only the children that are passed to the Provider
will get the updated values.
For instance, if we create a context myContext
and define name
and age
, we have to then set up a provider that will provide it's children that information to consume.
const myContext = createContext({
name: 'Bob',
age: 35
});
Now, we can use a Provider to pass that data down to children.
function HelloWorld() {
const { Provider } = myContext;
const [age, setAge] = useState(35)
const [name, setName] = useState('Bob')
return (
<Provider value={{ name, age }}>
<Profile />
</Provider>
)
}
name
and age
are the values we want to expose to our children, in this case we just have one child Profile
. Now we can access name
and age
in Profile
by destructuring them from our context.
function Profile(){
const { name, age } = useContext(myContext)
return (
<ul>
<li>{name}</li>
<li>{age}</li>
</ul>
)
}
But let's say somewhere else in our project we have component called Foo
and we want to access name
.
function Foo() {
const { name } = useContext(myContext) // you will only receive the default values defined in context
return <p>{name}</p>
}
This will return the default 'Bob' defined in myContext
. You may think, what was the point of that?
If we update our HelloWorld
component to actually update the name
and age
onMount, Foo
will still show Bob
.
function HelloWorld() {
const { Provider } = myContext;
const [age, setAge] = useState("");
const [name, setName] = useState("");
useEffect(() => {
setAge(40);
setName("Bill");
}, []);
return (
<Provider value={{ name, age }}>
<Profile />
</Provider>
);
}
function Profile() {
return (
<ul>
<li>{name}</li> // returns Bill
<li>{age}</li> // returns 40
</ul>
)
}
function Foo() {
return (
<p>{name}</p> // returns Bob
)
}
This is great when you have isolated features or components that need to pass around data and setters instead of prop drilling. You can have a component consume multiple contexts and you can have as many contexts as you want as long as they make sense. If you are passing a prop down just once, does not make sense to use context. If you have more complex passing of props, context may be worth it.

- 2,633
- 3
- 17
- 28
Changing props on a component causes it to re-render in most cases. Prop drilling with slow down your application as well as make it less readable.

- 1
- 1
-
Array.splice() modifies the parent array, and Array.slice() doesn't. – windows-user0 Jul 21 '20 at 13:07
-
Not a Number (NaN) is also a number. – refaelio Feb 01 '22 at 15:23