Connecting ProductsPage to the store

The first component we are going to connect to the store is going to be the ProductsPage component.

Let's open up ProductsPage.tsx and start to refactor it:

  1. First, let's import the connect function from React Redux:
import { connect } from "react-redux";

We'll use the connect function at the end of this section to connect the ProductsPage component to the store.

  1. Let's import the store state type and the getProducts action creator from our store:
import { IApplicationState } from "./Store";
import { getProducts } from "./ProductsActions";
  1. The ProductPage component won't contain any state now because this will be held in the Redux store. So, let's start by removing the state interface, the static getDerivedStateFromProps method, as well as the constructor. The ProductsPage component should now have the following shape:
class ProductsPage extends React.Component<RouteComponentProps> {
public async componentDidMount() { ... }
public render() { ... }
}
  1. The data is going to come from the store via props now. So, let's refactor our props interface:
interface IProps extends RouteComponentProps {
getProducts: typeof getProducts;
loading: boolean;
products: IProduct[];
}

class ProductsPage extends React.Component<IProps> { ... }

So, we'll get the following data passed from the store to our component:

  • The getProducts action creator
  • A flag called loading that indicates whether products are being fetched
  • The array of products
  1. So, let's adjust the componentDidMount life cycle method to invoke the getProducts action creator to start the process of products being fetched:
public componentDidMount() {
this.props.getProducts();
}
  1. We no longer reference the products array directly from ProductsData.ts. So, let's remove that from the input statement so that it looks as follows:
import { IProduct } from "./ProductsData";
  1. There is still no sign of the search state we used to have. We are just going to pick this up at the start of the render method now and not store it in state at all:
public render() {
const searchParams = new URLSearchParams(this.props.location.search);
const search = searchParams.get("search") || "";
return ( ... );
}
  1. Let's stay in the render method and replace the old state references:
<ul className="product-list">
{this.props.products.map(product => {
if (!search || (search && product.name.toLowerCase().indexOf(search.toLowerCase()) > -1)
) { ... }
})}
</ul>
  1. Under the class, but before the export statement, let's create a function that will map the state coming from the store to the component props:
const mapStateToProps = (store: IApplicationState) => {
return {
loading: store.products.productsLoading,
products: store.products.products
};
};

So, we are getting whether products are being loaded as well as the products from the store and passing these to our props.

  1. There is one more prop we need to map to and that is the getProducts function prop. Let's create another function that will map this action from the store to this function prop in the component:
const mapDispatchToProps = (dispatch: any) => {
return {
getProducts: () => dispatch(getProducts())
};
};
  1. There's one more job to do at the bottom of the file. This is to wrap the React Redux connect HOC around our ProductsPage component before it is exported:
export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductsPage);

The connect HOC connects the component to our store, which is provided to us by the Provider component higher up in the component tree. The connect HOC also invokes the mapper functions that map the state and action creators from the store into the component props.

  1. It's finally time to give our enhanced page a try. Let's start the dev server and the app via the terminal:
npm start

We should find the page behaves exactly the same as it did before. The only difference is now the state is being managed in our Redux store.

In the next section, we are going enhance our Products page by adding the loading spinner we already have in our project.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.108.9