The file structure that you helped implement in the last exercise works nicely when we add in React components. Take a look at the src folder in your workspace and you will find the following file structure (new files have a (+)
next to their name):
src/ |-- index.js |-- app/ |-- App.js (+) |-- store.js |-- components/ |-- FavoriteButton.js (+) |-- Recipe.js (+) |-- features/ |-- allRecipes/ |-- AllRecipes.js (+) |-- allRecipesSlice.js |-- favoriteRecipes/ |-- FavoriteRecipes.js (+) |-- favoriteRecipesSlice.js |-- searchTerm/ |-- SearchTerm.js (+) |-- searchTermSlice.js
If you look at the actual file structure in your code editor, you may notice a few unfamiliar files / directories not mentioned in the structure above. The test/ directory and index.compiled.js file are used to test your code on Codecademy. You can ignore them.
The new components are:
<App />
: The top-level component for the entire application.<AllRecipes />
: The component for rendering the recipes loaded from the “database”.<FavoriteRecipes />
: The component for rendering the recipes favorited by the user.<SearchTerm />
: The component for rendering the search bar that filters the visible recipes.<Recipe />
and<FavoriteButton />
: Generic components used by<AllRecipes />
and<FavoriteRecipes />
Aside from the generic components, each feature-related React component file is located in the same directory as the slice file that manages the data rendered by that component. For example, FavoriteRecipes.js and favoriteRecipesSlice.js are both in the src/features/favoriteRecipes/ directory.
Open the src/app/App.js file where the top-level component, <App />
, is stored. As in most React applications, this top-level component will render each feature-component and pass any data needed by those components as prop values. In Redux applications, the data passed to each feature-component includes:
- The slice of the
store
‘s state to be rendered. For example, thestate.searchTerm
slice is passed to the<SearchTerm />
component. - The
store.dispatch
method to trigger state changes through user interactions within the component. For example, the<SearchTerm />
component will need to dispatchsetSearchTerm()
actions.
This distribution of the store.dispatch
method and the slices of state to all of the feature-components, via the <App />
component, begins in the index.js file. Open up the src/index.js file where you will see some standard React code for rendering the top-level <App />
component. You’ll notice that the store
is missing and the <App />
component isn’t receiving any props!
Instructions
In order to pass the store
‘s current state and its dispatch
method to the <App />
component, the store
must first be imported into the index.js file.
At the top of index.js, import the store
from store.js.
Next, get the current state of the store
and pass it to the <App />
component as a prop called state
.
Note: You won’t see anything rendered until the next checkpoint!
The <App />
component isn’t rendering yet because it is expecting to receive a dispatch
method.
Pass the store.dispatch
method to the <App />
component as a prop called dispatch
.
If done correctly, you should see the <FavoriteRecipes />
and <AllRecipes />
components rendered (without data, for now)!
Why is the recipe data not being rendered? Remember that the state.allRecipes
slice begins as an empty array and the data is only loaded AFTER the user opens the page. This data fetch is happening but render
isn’t subscribed to changes to the store
yet!
At the bottom of index.js, use store.subscribe()
to subscribe the render
function to the store
such that each time the store
‘s state changes, the entire <App />
will be re-rendered.