Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

How to access redux-toolkit reducer/action from a class component using react-redux connect()?


I have a redux-toolkit store at store.js.

import { configureStore } from '@reduxjs/toolkit';
import productCurrency from './stateSlices/productCurrency';

const Store = configureStore({
        reducer: {
            productCurrency: productCurrency,
        },
    })
export default Store;

The createslice() function itself is in a different file and looks like this below.

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
        value: '$',
}

export const productCurrency = createSlice({
        name: 'productCurrency',
        initialState,
        reducers: {
            setproductCurrency(state, newState) {
                state.value = newState
            },
        },
})
export const { setproductCurrency } = productCurrency.actions;
export default productCurrency.reducer;

My issue is that I have a class component NavSection that needs to access the initial state and the reducer action setproductCurrency() to change the state. I am trying to use the react-redux connect() function to accomplish that.

const mapStateToProps = (state) => {
  const { productCurrency } = state
  return { productCurrency: productCurrency.value }
}

const mapDispatchToProps = (dispatch) => {
  return {
    setproductCurrency: () => dispatch(setproductCurrency()),
    dispatch,
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(NavSection);

Now, I am able to access the state by ussing this.props.productCurrency. Yet, if I try to access the setproductCurrency() by ussing this.props.setproductCurrency()... Chrome console gives me an error that "this.props.setproductCurrency() is not a function".

Is there a way of fixing this, or am I trying to do something impossible?

UPDATE #1

I think I just moved the ball in the right direction. I changed the onClick function to be an arrow function as shown below.

onClick={() => this.props.setproductCurrency('A$')}

Now, setproductCurrency() is considered a function, but it returns a different error when I click the button...

Objects are not valid as a React child (found: object with keys {type, payload}). If you meant to render a collection of children, use an array instead.

Why would this function now return an object? It is supposed to change the state and trigger a re-render of the page so that the class component can access the newly changed state.


Solution

  • To be clear, RTK has nothing to do with React-Redux, connect, or mapDispatch :)

    The current error of "Objects are not valid as a React child" is because your reducer is wrong. A reducer's signature is not (state, newState). It's (state, action). So, your line state.value = newStateis reallystate.value = action`, and that's assigning the entire Redux action object as a value into the state. That's definitely not correct conceptually.

    Instead, you need state.value = action.payload.