React Creating Context
Table of Contents + −
In the last lesson, React Introduction to Context API, you learned the three steps: create, provide, read. This lesson does the first one, so we’ll create a context with createContext and get it ready for the provider and readers that come next.
🤔 What does “creating context” mean?
Creating a context just means making the empty container that will hold your shared data.
- You call
createContext()once to make a context object. - That object is what everything else points to, so the provider that fills it and the components that read it all refer to the same one.
- You usually create it in its own file and export it, so any component can import it.
- It has no real value yet. That comes from the provider later, right?
So this step is small. You’re just making the named box.
🧩 Using createContext
You make a context by calling createContext, imported from React. You can pass a default value.
import { createContext } from "react";
// create the context with a default valueexport const ThemeContext = createContext("light");Read each part.
- We import
createContextfrom React. createContext("light")makes the context and sets"light"as its default value.- We
exportit, so the provider and any reader can import the sameThemeContext. - That name,
ThemeContext, is what you’ll pass to the provider and touseContextlater.
Name it for what it holds
Name your context after the data it carries, like ThemeContext, UserContext, or AuthContext. The capital first letter and Context suffix are the common convention, and they make the code easy to read.
🎯 The default value
The value you pass to createContext is the default. It’s used only when a component reads the context with no provider above it.
// default is "light"export const ThemeContext = createContext("light");
// later, a component with NO provider above reads "light"const theme = useContext(ThemeContext); // "light"Understand when the default matters.
- If there is a provider above the component, the reader gets the provider’s value, not the default.
- So most of the time the provider’s value wins, and the default is just a safety net.
- It’s also handy as documentation, since it shows the shape of value the context expects.
Don't rely on the default for real data
The default is a fallback, not where you store your actual app data. Your real, changing value comes from the provider. Set a sensible default (like "light" or null), but expect the provider to supply the live value.
📁 Putting context in its own file
A clean pattern is to create the context in its own small file and export it.
import { createContext } from "react";
export const ThemeContext = createContext("light");Why a separate file helps.
- The provider component imports
ThemeContextfrom here to fill it. - Every component that reads the context imports the same
ThemeContextfrom here. - So there’s one source of truth, and nothing gets out of sync.
⚠️ Common Mistakes
A common mistake is creating the context inside a component, so a new one is made on every render.
// ❌ created inside a component - a brand new context on every renderfunction App() { const ThemeContext = createContext("light"); // wrong place // ...}
// ✅ created once at the top level (module scope), outside any componentexport const ThemeContext = createContext("light");function App() { // ...}Keep these in mind.
- Don’t call
createContextinside a component. Create it once at the top level of a file. - Don’t forget to export it, or other files can’t import the same context.
- Don’t expect the default to hold your live data. It’s just a fallback.
✅ Best Practices
A few habits for creating context.
- Call
createContextonce, at the top level of a file, not inside a component. - Export the context so the provider and all readers share the same object.
- Name it clearly, like
ThemeContextorUserContext. - Give it a sensible default that shows the expected shape, like
"light"ornull.
One line, then move on
Creating the context really is just that one createContext line. The interesting work, giving it a real value and reading it, happens in the provider and readers, which are the next lessons.
🧩 What You’ve Learned
- ✅ Creating a context makes the shared container that the provider fills and readers read
- ✅ Use
createContext(defaultValue), imported from React - ✅ The default value is a fallback, used only when a component has no provider above it
- ✅ Create the context once at the top level of a file, not inside a component
- ✅ Export the context so the provider and all readers use the same object
- ✅ Name it clearly, like
ThemeContext, and give it a sensible default
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What does createContext do?
Why: createContext makes the context object itself. Filling it with a real value is the provider's job, and reading it is done with useContext.
- 2
When is the default value passed to createContext actually used?
Why: If a provider wraps the component, the reader gets the provider's value. The default is a fallback used only when there's no provider above.
- 3
Where should you call createContext?
Why: Create the context once at module scope. Calling it inside a component would make a new context on every render, which breaks sharing.
- 4
Why export the context object?
Why: Exporting it gives one source of truth. The provider and every reader import the same ThemeContext, so they all refer to the same context.
🚀 What’s Next?
Now you have a context object, but it’s still empty. Next you’ll wrap part of your app in the context’s Provider and give it a real value, so components inside can finally read shared data.