如何在redux-toolkit中正确存储action.payload?

问题描述 投票:0回答:2

我正在使用 redux 工具包从 API 获取用户并将用户的状态保存在商店中。

  userStore: {
    users: [],
    loading: true
  }
}

这显示在 firefox 中的 redux-toolkit 开发工具中。

我早就料到会这样。

  userStore: {
    users: Array[..], //an array of 10 users
    loading: false
  }
}

我已经在index.js中配置了商店

const store = configureStore({
    reducer: {
        userStore: usersReducer,
    },
});

export default store;

userSlice.js


const initialState = {
    users: [],
    loading: false,
};

export const userSlice = createSlice({
    name: 'users',
    initialState,
    reducers: {
        receivedUserList: (state, action) => {
            state.users = action.payload;
        },
        toggleLoadingUsers: (state) => {
            state.loading = !state.loading;
        },
    },
});

export const { receivedUserList, toggleLoadingUsers } = userSlice.actions;

export default userSlice.reducer;

用户操作.js


export const fetchUsers = (data) => async (dispatch) => {
    try {
        dispatch(toggleLoadingUsers());
        const response = await userAPI.get('/users');
        dispatch(receivedUserList(response.data));
        dispatch(toggleLoadingUsers());
    } catch (error) {
        console.log(error);
    }
};

我在 App.js 中使用 fetchusers,如下所示。

    const dispatch = useDispatch();
    const { users, loading } = useSelector((state) => state.userStore);
    useEffect(() => {
        console.log('something');
        console.log(loading);
        console.log(users);
        dispatch(fetchUsers());
    }, []);

这没有正确更新状态。获取用户后如何设置状态? 我已经通过了 src/index.js 中 ./store/index.js 中的商店

import store from './store/index';
import { Provider } from 'react-redux';

ReactDOM.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>,
    document.getElementById('root')
);
reactjs react-redux redux-toolkit
2个回答
4
投票

Redux 工具包背后的想法是删除操作、类型和化简器的样板代码,并将它们统一到单个切片中。

让我们重构用户切片代码如下。


import { createAsyncThunk } from "@reduxjs/toolkit";

export const fetchUsers = createAsyncThunk("users/fetchUsers", async (data) => {
  const response = await userAPI.get("/users");

  return response.data;
});

const initialState = {
  users: [],
  loading: false,
};

export const userSlice = createSlice({
  name: "users",
  initialState,
  reducers: {
    receivedUserList: (state, action) => {
      state.users = action.payload;
    },
    toggleLoadingUsers: (state) => {
      state.loading = !state.loading;
    },
  },

  extraReducers: {
    [fetchUsers.pending]: (state, action) => {
      state.loading = true;
    },
    [fetchUsers.fulfilled]: (state, action) => {
      state.loading = false;
      state.users = [...state.users, ...action.payload];
    },
    [fetchUsers.rejected]: (state, action) => {
      state.loading = true;
      state.error = action.error;
    },
  },
});

export const { receivedUserList, toggleLoadingUsers } = userSlice.actions;

export default userSlice.reducer;


然后从

fetchUsers
 导入 
userSlice

//top-level import 
import {fetchUsers} from "../userSlice"


    const dispatch = useDispatch();
    const { users, loading } = useSelector((state) => state.userStore);
    useEffect(() => {
        console.log('something');
        console.log(loading);
        console.log(users);
        dispatch(fetchUsers());
    }, []);


0
投票
**store code**
const store = configureStore({
    reducer: {
        users: usersReducer,
    },
});

you have to add same name as you wrote in Slice

**while dispatchig data**

const dispatch = useDispatch();
    const { users, loading } = useSelector((state) => state.users);
    useEffect(() => {
        console.log('something');
        console.log(loading);
        console.log(users);
        dispatch(fetchUsers());
    }, []);

**instead of usersStore keeep name same as in store**
© www.soinside.com 2019 - 2024. All rights reserved.