简体   繁体   English

如何使用带有 RTK 查询的 useEffect 挂钩更新 state?

[英]How to update state using useEffect hook with RTK Query?

I want to update my state in reducer when GET call returns data successfully.GET调用成功返回数据时,我想在 reducer 中更新我的 state。 I am dispatching list of employees using useEffect but something is not going right.我正在使用useEffect派遣员工名单,但有些事情不对劲。

My employeesList:[] is going undefined in Employees component.我的employeesList:[]Employees组件中undefined

employeeApiSlice.js employeeApiSlice.js

import { apiSlice } from "../../app/api/apiSlice";

export const employeesApiSlice = apiSlice.injectEndpoints({
    endpoints: (builder) => ({
        getEmployees: builder.query({
            query: () => ({
                url:'/protected/employee'
            }),
            keepUnusedDataFor: 5
        })
    }),
});

export const { useGetEmployeesQuery } = employeesApiSlice;

employeesSlice.js employeesSlice.js

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

const initialState = {
    employeesList: []
};

export const employeesSlice = createSlice({
    name: 'employees',
    initialState,
    reducers: {
        storeEmployees: (state, action) => {
            state.employeesList = action.payload;
        },
    }
});

export const { storeEmployees } = employeesSlice.actions;
export default employeesSlice.reducer;

employees.js component employees.js 组件

import React, { useEffect } from 'react';
import {Table} from "react-bootstrap";

import { useDispatch, useSelector } from "react-redux";
import { useGetEmployeesQuery } from "./employeesApiSlice";
import { storeEmployees } from "./employeesSlice";

function Employees(){

    const dispatch = useDispatch();
    const { data, isLoading, isSuccess, isError, error } = useGetEmployeesQuery();

    useEffect(() => {
        dispatch(storeEmployees(data));
    }, []);

    
    const { employeesList } = useSelector(state => state.employees);

    return (
                <Table size='sm' striped bordered hover responsive>
                    <thead>
                    <tr>
                        <th>No</th>
                        <th>First Name</th>
                        <th>Last Name</th>
                        <th>Position</th>
                        <th>Record Created</th>
                        <th>Record Updated</th>
                    </tr>
                    </thead>
                    <tbody>
                    {employeesList.map((employee, i) => {
                        return (
                            <tr key={i}>
                                <td>{i+1}</td>
                                <td>{employee.firstName}</td>
                                <td>{employee.lastName}</td>
                                <td>{employee.position}</td>
                                <td>{employee.recordCreatedAt}</td>
                                <td>{employee.recordUpdatedAt}</td>
                            </tr>
                        )
                    })}
                    </tbody>
                </Table>
            )
}

export default Employees;

You would not use the detour with the component and useEffect , you can just add an extraReducer to your slice.您不会将绕道与组件和useEffect使用,您可以只向切片添加一个extraReducer

export const employeesSlice = createSlice({
  name: "employees",
  initialState,
  reducers: {
    storeEmployees: (state, action) => {
      state.employeesList = action.payload;
    },
  },
  extraReducers: (builder) => {
    builder.addMatcher(
      api.endpoints.getEmployees.matchFulfilled,
      (state, action) => {
        state.employeesList = action.payload;
      }
    );
  },
});

That said, you should probably not copy RTK Query state into a slice .也就是说,您可能不应该将 RTK 查询 state 复制到切片中。 As you will lose out on a lot of RTK Query features and things might run out of sync.因为您会失去很多 RTK 查询功能,而且事情可能会不同步。 Usually, you should keep RTK Query state just in RTK Query - and call useGetEmployeesQuery in all components where you need that data.通常,您应该仅在 RTK 查询中保留 RTK 查询 state - 并在需要该数据的所有组件中调用useGetEmployeesQuery That's what it is designed for.这就是它的设计目的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM