reactjs redux工具箱中未调用createAsyncThunk函数

kzipqqlq  于 2023-06-22  发布在  React
关注(0)|答案(1)|浏览(92)

我必须在React和参考应用程序的应用程序是https://www.griddynamics.com/services/global-team/outsourcing-calculator
下面是我尝试过的代码:resourceSlice.js文件

import axios from 'axios';
const { createSlice, current, createAsyncThunk } = require('@reduxjs/toolkit');
const API_URL = "https://xxxx:xxxxxx@demo.xxxxxx.net/xxxx-2023/calapi"

// Thunks
export const fetchResuorces = createAsyncThunk('resources/fetch', async () => {
    console.log("In Fetch Resources by dispatch")
    try {
        const response = await axios.get(API_URL, {
            headers: {
                'Content-Type': 'application/json'
            },
            auth: {
                username: 'xxxx',
                password: 'xxxxxxxxx'
            }
        });
        console.log('response', response);
        return response?.data
    } catch (err) {
        console.log(err)
    }
});

const resourceSlice = createSlice({
    name: 'resource',
    initialState: {
       rows: [{
        index: 1
       }],
       roles: [
        {
            "id": 1,
            "rtype": "Engineers ( ASP.NET )",
            "experience": [
                {
                    "id": 1,
                    "role": "High end Developer",
                    "rtypeId": 1,
                    "experience": 5
                },
                {
                    "id": 2,
                    "role": "Med level Developer",
                    "rtypeId": 1,
                    "experience": 2
                }
            ]
        }
      ]
    },
    reducers: {
        add(state, action) {
            state.rows.push({
                index: 2
            });
        },
        remove(state, action) {
            console.log('remove called')
            console.log(state.rows)
            return state.rows.filter((item, index) =>
                item.id !== action.payload
            );
        },
        getRoleLevels(state, action) {
            let selectedRoleId = action.payload;
            console.log(selectedRoleId)
        }
    },
    extraReducers: (builder) => {
        console.log('extra builder')
        builder
            .addCase(fetchResuorces.pending, (state) => {
                console.log('Pending Response')
            })
            .addCase(fetchResuorces.fulfilled, (state, action) => {
                console.log('fulfilled')
                return action.payload
            })
            .addCase(fetchResuorces.rejected, (state) => {
                console.log('Call Rejected')
            })
    },
})

export const { add, remove, getRoleLevels } = resourceSlice.actions;
export default resourceSlice.reducer;

resource.js文件

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useSelector, useDispatch } from 'react-redux';
import { add, remove, getRoleLevels } from '../store/resourceSlice';
import { fetchResuorces } from '../store/resourceSlice';

const ResourceComponent = (props) => {

    const dispatch = useDispatch();
    const resources = useSelector((state) => state.resource);

    useEffect(() => {
        dispatch(fetchResuorces)
    }, [])

    const handleAdd = () => {
        console.log("called handleAdd")
        dispatch(add())
    }

    const handleRemove = (index) => {
        console.log('index ID', index)
        dispatch(remove(index))
    }

    const getLevels = (roleId) => {
        //dispatch(getRoleLevels(roleId))
    }

    console.log('resources', resources)
    return (
        <>
            <div className="tab-content mt-5">
                <div className="mr-10">
                    <h3>Select resources you need</h3>
                    
                    {
                        resources.rows.map((resource, index) => {
                            return (
                                <div className=" select-mode row row-cols-lg-auto g-3 align-items-center" key={index}>
                                    <div className="mb-3">
                                        <select className="tech">
                                            { resources.roles.length > 0 && 
                                                resources.roles.map((role, roleIndex) => {
                                                    return (
                                                        <option key={roleIndex} value={role.id}>{role.rtype}</option>
                                                    )
                                                })
                                            }
                                        </select>
                                    </div >
                                    <div className="mb-3">

                                        <select defaultValue={resource.rtypeId} className="level">
                                            <option>Senior</option>
                                            <option>Intermediate</option>
                                            <option>Junior</option>
                                        </select>
                                    </div>
                                    <div className="mb-3">
                                        <select className="count">
                                            <option>1</option>
                                            <option>2</option>
                                            <option>3</option>
                                        </select>
                                    </div>
                                    <div className="mb-3">
                                        <select className="count">
                                            <option>Hour(s)</option>
                                            <option>Day(s)</option>
                                            <option>Month(s)</option>
                                            <option>Year(s)</option>
                                        </select>
                                    </div>
                                    <div className="mb-3">
                                        <input type="number" />
                                    </div>
                                    <div className="mb-3">
                                        <button
                                            className="btn btn-cross btn-cross-yellow-dark remove-dev ml-2"
                                            onClick={() => handleRemove(index)}
                                        >
                                            <img src={props.crossSymbol} alt="remove" />
                                        </button>
                                    </div>
                                </div>
                            )
                        })
                    }
                    <button
                        id="add-position"
                        className="btn btn-link color-primary font-weight-normal plus-icon"
                        onClick={() => handleAdd()}
                    >
                        <img src={props.plusSymbol} alt="Add" />
                        Add a position
                    </button>
                </div>
            </div>
        </>
    )
}

export default ResourceComponent;

这是如下的文件夹结构:

有人能告诉我

  • #1是否可以同时使用reducersextraReducers*,即* * extraReducers**用于thunk函数API调用,reducers用于内部状态管理,如添加或删除行?
  • *#2为什么fetchResuorcescreateAsyncThunk函数默认不被调用,让我通过API获取值并显示在组件上?尽管console.log('extra builder')在extraReducers**片段中打印

是否有什么代码,我错过了,请建议

vuktfyat

vuktfyat1#

#1是否可以同时使用reducersextraReducers,即extraReducers用于thunk函数API调用,reducers用于内部状态管理,如添加或删除行?

是的,您完全可以使用两种内部减速器,例如。reducers和外部减速器,例如extraReducers。区别基本上是reducers用于处理切片自身生成的动作,例如:resourceSlice状态片中的addremovegetRoleLevels,而extraReducers用于处理片外生成的任何操作。这些额外的reducer情况可以是异步Thunk动作或从其他状态片生成的动作。

#2为什么fetchResuorcescreateAsyncThunk函数默认不被调用,让我通过API获取值并显示在组件上?尽管console.log('extra builder')在extraReducers片段中打印

这里的问题是,UI代码实际上并没有分派fetchResuorces操作。需要调用操作,例如:dispatch(fetchResuorces())而不是dispatch(fetchResuorces)

useEffect(() => {
  dispatch(fetchResuorces()); // <-- invoke fetchResuorces!
}, []);

console.log('extra builder')在处理resourceSlice代码时执行,例如当应用程序正在安装并且商店被示例化时,所以这就是为什么你看到那个日志没有问题。

相关问题