Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redux-toolkit action not triggered in reducer

Tags:

I'm trying to trigger a simple action using @reduxjs/Toolkit but it's not working.

I see that the action is dispatched but it's like the slice reducer is not listening to it or something.

const say = createAction("ui/say", what => ({ payload: what }));

const uiSlice = createSlice({
  name: "ui",
  initialState: { said: "" },
  reducers: {
    [say.type]: (state, action) => {
      console.log("saying", action.payload); //<-- not showing, why?
      state.currentList = action.payload;
    }
  }
});

const store = configureStore({
  reducer: combineReducers({
    ui: uiSlice.reducer
  })
});

const Chat = () => {
  const dispatch = useDispatch();
  const [whatToSay, setWhatToSay] = useState("");
  const whatWasSaid = useSelector(state => state.ui.said);

  const onSubmit = e => {
    e.preventDefault();
    dispatch(say(whatToSay));
    setWhatToSay("");
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <input type="text" onChange={e => setWhatToSay(e.target.value)} />
        <button>Say</button>
      </form>
      {whatWasSaid ? <p>You said: {whatWasSaid}</p> : <p>Say something</p>}
    </div>
  );
};

Here's a minimal reproducing example: https://codesandbox.io/s/redux-toolkit-0tzxs?file=/src/index.js

like image 458
Tecnogirl Avatar asked Jun 07 '20 13:06

Tecnogirl


People also ask

How do you make a reducer in Redux toolkit?

Create a Redux State Slice​Add a new file named src/features/counter/counterSlice.js . In that file, import the createSlice API from Redux Toolkit. Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated.

Can we dispatch actions from reducers?

Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.

Does Redux Toolkit need thunk?

Redux Toolkit's RTK Query data fetching API is a purpose built data fetching and caching solution for Redux apps, and can eliminate the need to write any thunks or reducers to manage data fetching.


1 Answers

I think you mismatched the createSlice API.

From your code, you trying to implement a listener for an action, so you might want to use extraReducers instead:

const uiSlice = createSlice({
  name: "ui",
  initialState: { said: "" },
  // Not reducers: {}
  extraReducers: {
    [say.type]: (state, action) => {
      console.log("saying", action.payload);
      state.currentList = action.payload;
    }
  }
});

Note the reducers prop of createSlice API:

reducers: Object<string, ReducerFunction | ReducerAndPrepareObject>

If you want to use say in reducers it should be:

const say = (state, payload) => {
  console.log("saying", payload);
  state.currentList = payload;
};


const uiSlice = createSlice({
  name: "ui",
  initialState: { said: "" },
  reducers: { say }
});

// Usage
dispatch(uiSlice.actions.say(whatToSay));

Edit redux-toolkit

@markerikson: with createSlice, the reducers field is for defining reducers and generating actions that will match those reducers. The extraReducers field is for handling actions that were already defined elsewhere.

like image 132
Dennis Vash Avatar answered Oct 12 '22 22:10

Dennis Vash