Действие redux-toolkit не запускается в редукторе

Я пытаюсь запустить простое действие с помощью @ reduxjs / Toolkit, но оно не работает.

Я вижу, что действие отправлено, но это похоже на то, что редуктор среза его не слушает или что-то в этом роде.

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>
  );
};

Вот минимальный пример воспроизведения: https://codesandbox.io/s/redux-toolkit-0tzxs?file=/src/index.js


person Tecnogirl    schedule 07.06.2020    source источник


Ответы (1)


Я думаю, вы не соответствовали createSlice API.

Из своего кода вы пытаетесь реализовать прослушиватель для действия, поэтому вы можете вместо этого использовать extraReducers:

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

Обратите внимание на reducers опору createSlice API:

reducers: Object<string, ReducerFunction | ReducerAndPrepareObject>

Если вы хотите использовать say в reducers, это должно быть:

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));

 Редактировать redux-toolkit

@markerikson: с createSlice поле redurs предназначено для определения редукторов и генерации действий, которые будут соответствовать этим редукторам. Поле extraReducers предназначено для обработки действий, которые уже были определены в другом месте.

person Dennis Vash    schedule 07.06.2020
comment
Я думал, что extraReducers предназначен только для обработки асинхронных действий (из документации). Теперь я в замешательстве: почему существует 2 типа и когда мы должны использовать каждый из них? Кроме того, как будут работать редукторы: {say}, поскольку say является создателем действий? Как мы устанавливаем указанное поле состояния? - person Tecnogirl; 07.06.2020
comment
Для асинхронных действий вы используете createAsyncThunk API, extraReducers - для создания редукторов, но это зависит от других действий, кроме среза, в этом примере размещение say действия там бесполезно. В документации много примеров, не могу лучше объяснить - person Dennis Vash; 07.06.2020
comment
Вы задаете много хороших вопросов, поэтому, пожалуйста, просто открывайте для этого новые темы, я ответил на исходный вопрос, и мы должны сосредоточиться на нем. - person Dennis Vash; 07.06.2020
comment
Да вы правы, {say} должно быть от createReducer, мое плохое. - person Dennis Vash; 07.06.2020
comment
Вы сказали, что действие say не должно быть в extraReducers, поскольку оно принадлежит uiSlice, и я это понимаю. Но приведенный в вашем ответе пример неверен с редукторами: {say}. Можете ли вы отредактировать свой ответ и включить его правильно? То есть, используя createAction и createSlice, как мы добавляем действие в срез? - person Tecnogirl; 07.06.2020
comment
Я обновил ответ, вы тоже можете проверить песочницу. - person Dennis Vash; 07.06.2020
comment
Чтобы расширить это: с createSlice поле reducers предназначено для определения редукторов и генерации действий, которые будут соответствовать этим редукторам. Поле extraReducers предназначено для обработки действий, которые уже были определены в другом месте. - person markerikson; 08.06.2020