I’m building a react app with redux and I have a problem.
I have a component connected to the redux store and even though I dispatch actions those actions are not received from the reducer thus the state won’t change.
Here’s the code of the component:
import React from "react"; import { connect } from "react-redux"; import { setOrderFilter } from "store/filters"; const mapStateToProps = (state) => { return { filters: state.entities.filters, }; }; const mapDispatchToProps = { setOrderFilter, }; function Filters(props) { const { order } = props.filters; console.log(setOrderFilter({test: 1}) // {type: "filters/setOrderFilter", payload: {…}} // payload: {test: 1} // type: "filters/setOrderFilter" const handleOrder = (event) => { setOrderFilter({ order: event.target.value }); }; return ( <div> <label> Date order: <select value={order} onChange={(e) => handleOrder(e)}> <option value="ascending">ascending</option> <option value="descending">descending</option> </select> </label> </div> ); } export default connect(mapStateToProps, mapDispatchToProps)(Filters);
Here’s the filters.js
file in the store:
import { createSlice } from "@reduxjs/toolkit"; const slice = createSlice({ name: "filters", initialState: { order: "descending", }, reducers: { setOrderFilter: (state, action) => { console.log("here"); state.order = action.payload; }, }, }); export const { setOrderFilter } = slice.actions; export default slice.reducer;
Everything looks fine, even console.log
the action setOrderFilter
yields the correct result, but when I change the select in the UI, no action is dispatched and the value doesn’t change…
the console.log
inside the reducer is never printed.
The store is configured with an api middleware to handle async code:
import axios from "axios"; import * as actions from "store/api"; import getBaseUrl from "helpers/getApiUrl"; const api = ({ dispatch }) => (next) => async (action) => { console.log(action) if (action.type !== actions.apiCallBegan.type) return next(action); .... }; export default api;
The calls from other entities are printed and visible in the middleware, the one from filters
are not even printed there.
What am I missing?
Advertisement
Answer
The problem is in the handleOrder function.
const handleOrder = (event) => { setOrderFilter({ order: event.target.value }); };
You have to use the connected setOrderFilter
. That is in the component’s props.
const handleOrder = (event) => { props.setOrderFilter({ order: event.target.value }); };
It’s an easy mistake to make when using the mapDispatchToProps shorthand. There is a function in scope called setOrderFilter
, but when you use that, you will just create the action object, but it will not be dispatched to redux.