首页 > 解决方案 > 当 API 发布成功时,发送一个 get 请求 - React/Redux

问题描述

我有一个小应用程序,它显示一个列表组件(JobsList)和另一个包含文本字段和提交按钮(CreateJob)的组件。虽然我能够使用 API 数据(通过 Redux)填充 JobsList,但我不确定如何在 CreateJob 中成功发布新工作后使用新的 API 调用更新 JobsList。这是我到目前为止的代码:

JobsList.js

import React, { Fragment, useEffect } from 'react';
import { connect } from 'react-redux';
import JobCard from './JobCard';
import CreateJob from './CreateJob';
import api from './Api';
import { JOBS_LOADED } from './ActionTypes';

const JobsList = ({ jobs, onLoad }) => {

useEffect(() => {
    const fetchJobs = async () => {

        try {
            const data = await api.Jobs.getAll();
            onLoad({ data });
        } catch (err) {
            console.error(err);
        }
    };
    fetchJobs();
}, [onLoad]);

return (
    <Fragment>
        <CreateJob />
        {teams.map(job => (
            <JobCard job={job} key={team.jobId} />
        ))}
    </Fragment>
);
}

const mapStateToProps = state => ({
    jobs: state.jobsReducer.teams
});

const mapDispatchToProps = dispatch => ({
    onLoad: payload =>
        dispatch({ type: JOBS_LOADED, payload }),
});

export default connect(mapStateToProps, mapDispatchToProps)(JobsViewer);

CreateJob.js

import React, { useState } from 'react';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import api from './Api';

const CreateJob = () => {
const [state, setState] = React.useState({
    jobName: '',
    creator: ''
});

const handleInputChange = event => {
    setState({
        ...state,
        [event.target.name]: event.target.value
    });
    // validation stuff
}

const handleSubmit = async e => {
    api.Jobs.create({state})
    try {
        await request;
        // Reload the Jobs list so it does an another API request to get all new data
        // DO I CALL A DISPATCH HERE?????
    } catch (err) {
        console.error(err);
    }
}

return (
    <div>
        <TextField
            name="jobName"
            value={state.jobName || ''}
            onChange={handleInputChange}
        />
        <Button onClick={handleSubmit}>Create job</Button>
    </div>
);
}

export default CreateJob;

JobsReducer.js

import { TEAMS_LOADED } from './ActionTypes';

export default (state = {teams: []}, action) => {
switch (action.type) {
    case TEAMS_LOADED:
        return {
            ...state,
            teams: action.payload.data,
        };
    default:
        return state;
}
};

在中的成功结果中handleSubmitCreateJob.js我如何触发/调度一个新的 API 调用来更新 JobsList CreateJob.js?我是 react/redux 的新手,所以对任何糟糕的代码表示歉意。非常感谢对学习者的任何建议。

标签: reactjsredux

解决方案


采用的简化解决方案是将用于获取作业的函数包装为 JobsList 中的变量,并将其作为道具分配给 CreateJob。然后在 CreateJob 中,由您来更新工作列表。

该解决方案的不足之处在于它没有尽可能多地利用 redux。最好在 JobsReducer.js 中为共享操作(fetch_jobs)创建操作创建器,并将这些操作作为道具映射到需要它的组件。

JobsReducer.js

export const fetchJobsAsync = {
  return dispatch => {
    try {
      const data = await api.Jobs.getAll();
      dispatch({type: TEAMS_LOADED, payload: {data}})
    } catch (err) {
      console.error(err);
    }
  }
}

提示:您必须安装redux-thunk才能启用异步操作。

之后,您将能够通过调度操作而不是直接调用 API 来触发 API 以从任何组件更新作业(或团队)。

JobsList.jsx 或 CreateJob.js

const mapDispatchToProps = dispatch => ({
  fetchAll: () => dispatch(fetchJobsAsync())
})

在 CreateJob.js 结束时,和调用其他常规函数一样调用 fetchAll 重新加载作业列表是完全一样的。

而且,如果您可以更进一步,请将创建新作业的 API 调用移动到 reducer 并将其包装为一个操作。在其中,如果满足预期条件(如果创建新作业成功完成),则调度 fetchJobsAsync。然后你会得到一个更清晰的组件树,只有同步道具,没有关于何时/如何重新加载作业列表的数据逻辑。


推荐阅读