Hi everyone,
I’m currently working on the Core Redux API project and am on the “Extra Challenges” point.
I can’t get my SearchTerm component to render and wondered if you could help me to work out where I have gone wrong.
Originally, the code was rendering but when I added the SearchTerm component to App.js, it stopped rendering. I then tried removing it again to see if it would re-render but it won’t
Here’s my code:
searchTermSlice.js
/*
Extra Credit:
1. Create a function called searchTermReducer that can handle the following action types:
* 'searchTerm/setSearchTerm'
* 'searchTerm/clearSearchTerm'
* Don't forget to set the initial state and return state by default!
*/
const initialState = '';
export const searchTermReducer = (state = initialState, action) => {
switch (action.type) {
case 'searchTerm/setSearchTerm': {
return action.payload
}
case 'searchTerm/clearSearchTerm': {
return '';
}
default: {
return initialState = '';
}
}
}
/*2. Create a function called setSearchTerm
* It has one parameter, term
* It returns an action object whose payload is the term value
* See SearchTerm.js for how this will be used.
*/
export const setSearchTerm = (term) => {
return {
type: 'searchTerm/setSearchTerm',
payload: term
}
}
/*
3. Create a function called clearSearchTerm
* It returns an action object with no payload
* See SearchTerm.js for how this will be used.
*/
export const clearSearchTerm = () => {
return {
type: 'searchTerm/clearSearchTerm'
}
}
SearchTerm.js
import React from 'react';
import { setSearchTerm, clearSearchTerm } from './searchTermSlice.js';
const searchIconUrl =
'https://static-assets.codecademy.com/Courses/Learn-Redux/Recipes-App/icons/search.svg';
const clearIconUrl =
'https://static-assets.codecademy.com/Courses/Learn-Redux/Recipes-App/icons/clear.svg';
export const SearchTerm = (props) => {
const { searchTerm, dispatch } = props;
const onSearchTermChangeHandler = (e) => {
const userInput = e.target.value;
dispatch(setSearchTerm(userInput));
};
const onClearSearchTermHandler = () => {
dispatch(clearSearchTerm());
};
return (
<div id="search-container">
<img id="search-icon" alt="" src={searchIconUrl} />
<input
id="search"
type="text"
value={searchTerm}
onChange={onSearchTermChangeHandler}
placeholder="Search products"
/>
{searchTerm.length > 0 && (
<button
onClick={onClearSearchTermHandler}
type="button"
id="search-clear-button"
>
<img src={clearIconUrl} alt="" />
</button>
)}
</div>
);
};
store.js
// Import createStore and combineReducers here.
import { createStore, combineReducers } from 'redux';
// Import the slice reducers here.
//../ means the parent of the app directory, i.e. src
import { inventoryReducer } from '../features/inventory/inventorySlice.js';
import { cartReducer } from '../features/cart/cartSlice.js';
import { currencyFilterReducer } from '../features/currencyFilter/currencyFilterSlice.js';
import { searchTermReducer } from '../features/searchTerm/searchTermSlice.js';
// Create and export the store here.
export const store = createStore(combineReducers({
inventory: inventoryReducer,
cart: cartReducer,
currencyFilter: currencyFilterReducer,
searchTerm: searchTermReducer
}));
index.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import { App } from './app/App.js';
const root = createRoot(document.getElementById('root'));
// Import the store here.
//the current directory is src, hence './'
import { store } from './app/store.js';
// Pass state and dispatch props to the <App /> component. This makes these props available to the entire application
const render = () => {
root.render(
<App
state={store.getState()}
dispatch={store.dispatch}
/>)
};
render();
// Subscribe render to the store.
// This method ensures that when
// any state changes occur,
// the components are re-rendered
// with the most up-to-date data
store.subscribe(render)
App.js
import React from 'react';
import { Inventory } from '../features/inventory/Inventory.js';
import { CurrencyFilter } from '../features/currencyFilter/CurrencyFilter.js';
// Import the Cart component here.
import { Cart } from '../features/cart/Cart.js';
import { SearchTerm } from '../features/searchTerm/SearchTerm.js';
// Render the Cart component below <Inventory />
export const App = (props) => {
const { state, dispatch } = props;
return (
<div>
{/*The slice of state is state.currencyFilter */}
<CurrencyFilter
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
<SearchTerm
searchTerm={state.searchTerm}
dispatch={dispatch}
/>
<Inventory
inventory={getFilteredItems(state.inventory, state.searchTerm)}
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
<Cart
cart={state.cart}
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
</div>
);
function getFilteredItems(items, searchTerm) {
return items.filter(items => items.name.toLowerCase().includes(searchTerm.toLowerCase()))
};
}
Thank you!