# Step 2.4 - React Context (Demo) [Lessons](../) | [Exercise](./exercise/) | [Demo](./demo/) In this step, we describe some problems we encounter when creating a more complex application. We will solve these problems with the React Context API. The Context API consists of: 1. Provider component 2. Consuming context from a Class Component 3. Consuming context from a Functional Component --- For a single component, React gives us a mental model like this: ``` (props) => view; ``` In a real application, these functions are composed. It looks more like this: ![](../../assets/todo-components.png) ## Problems in a Complex Application 1. Data needs to be passed down from component to component via props. Even when some components do not need to know about some data. 2. There is a lack of coordination of changes that can happen to the data Even in our simple application, we saw this problem. For example, `` has this props interface: ```ts interface TodoListProps { complete: (id: string) => void; remove: (id: string) => void; todos: Store['todos']; filter: FilterTypes; edit: (id: string, label: string) => void; } ``` All of these props are not used, except to be passed down to a child Component, `TodoListItem`: ```js ``` ## Context API Let's solve the first one with the Context API. A `context` is a special way for React to share data from components to their descendant children components without having to explicitly pass down through props at every level of the tree. We create a context by calling `createContext()` with some initial data: ```ts const TodoContext = React.createContext(); ``` Now that we have a `TodoContext` stuffed with some initial state, we will wrap `TodoApp` component with `TodoContext.Provider` so that it can provide data to all its children: ```js class TodoApp extends React.Component { render() { return (
); } } ``` Inside the children components, like the `` component, the value can be access from the component's `context` prop like this: ```js class TodoHeader extends React.Component { render() { // Step 1: use the context prop return
Filter is {this.context.filter}
; } } // Step 2: be sure to set the contextType property of the component class TodoHeader.contextType = TodoContext; ``` If you're using the functional component syntax, you can access the context with the `useContext()` function (we are using the function passed down inside the context, in this case): ```js const TodoFooter = props => { const context = useContext(TodoContext); return (
); }; ```