4.13 state raise.
In this short lesson we step back to look at what we just built in terms of React patterns. We are using a prop — onAddExpense — to call a function that we received from the parent. Calling a function passed via props is not, by itself, what is called lifting state up. What truly lifts state is the fact that we also pass data to that function when we call it.
By doing so we deliberately remove the data from the component that produced it: NewExpense does not keep the expense it just received. Instead it forwards it up to the App component, where it can be turned into shared state through the addExpenseHandler. For now we only log it inside App.js, but that is already the right place for it to live.
Why App is the correct destination
ExpenseFormis actually the component that collects user input and stores it temporarily withuseState.ExpenseFormthen hands its data toNewExpense, which is its direct parent.NewExpensein turn hands the enriched expense toApp, the first ancestor it shares with theExpenseslist.- Since
Expensesalso needs to see the new entry, the only component that has access to bothNewExpenseandExpensesisApp— so that is where the state must live.
This pattern — bubbling state from a leaf component up through props until you reach the closest common ancestor — is called lifting state up. You will encounter it again and again throughout this course, and we will keep explaining it in detail. See you in the next lesson.
Summary
This lesson covers the fundamental React pattern of lifting state up through component hierarchy. Rather than storing data in child components, you pass callback functions as props that allow child components to communicate data back to parent components. The parent (App component) then becomes the centralized state manager, enabling data to be shared across sibling components and preventing data duplication.
Key points
- Lifting state means moving data management from child components to parent components via callback functions passed as props
- Child components (like ExpenseForm) collect user input and pass that data back to the parent through function props, rather than storing it locally
- The parent component (App) receives the lifted data and can then use it across multiple child components or log it to the console
- This pattern prevents data silos and ensures a single source of truth for shared state across your component tree
- Lifting state requires understanding component hierarchy—identify which parent component needs access to the data for multiple children
FAQ
Why should I lift state up instead of keeping data in child components?
Lifting state allows multiple sibling components to access and share the same data. If you keep data only in child components, other components cannot use or respond to that data. By lifting state to a common parent, you create a single source of truth that all relevant children can access.
How do I pass data from a child component back to the parent?
The parent passes a callback function to the child as a prop. The child calls this function and passes the data as arguments. The parent receives this data in the callback and can then manage it or update state accordingly.
What component should 'own' the lifted state?
The state should be owned by the lowest common parent component that needs access to it. If both the ExpenseForm and ExpenseList need the data, lift it to their shared parent (App component).