You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Redux中API POST成功后如何触发GET请求更新JobsList?

Hey there! Let's break down how to fix this and get your JobsList updating after creating a new job. First, let's spot a few small issues in your existing code that might be causing confusion, then we'll tackle the main problem.

First, Fix the Tiny Typos & Inconsistencies

Before we solve the main issue, let's clean up some small mistakes that'll make your code work as expected:

  1. JobsList.js: You're using teams.map but your prop is named jobs — should be jobs.map. Also, your component is named JobsList but you're exporting JobsViewer at the end, that's a typo.
  2. Action Type Mismatch: In JobsList you use JOBS_LOADED, but your reducer listens for TEAMS_LOADED. Pick one name (like JOBS_LOADED to match your job-focused code) and make it consistent everywhere.
  3. CreateJob.js: Your API call has a bug — you need to assign the request to a variable before awaiting it: const request = api.Jobs.create(state); (also, no need to wrap state in an extra object).

Solution 1: Dispatch a "Fetch Jobs" Action After Submission (Beginner-Friendly)

This is the most straightforward approach. We'll connect CreateJob to Redux (or use Redux Hooks) so it can trigger the same job-fetching logic that JobsList uses.

Option A: Using connect (Classic Redux)

Update 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';
import { connect } from 'react-redux';
import { JOBS_LOADED } from './ActionTypes';

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

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

  const handleSubmit = async e => {
    e.preventDefault(); // Stop default form reload behavior
    try {
      await api.Jobs.create(state);
      // Trigger a refresh of the jobs list
      await refreshJobs();
      // Reset the form
      setState({ jobName: '', creator: '' });
    } catch (err) {
      console.error(err);
    }
  }

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

const mapDispatchToProps = dispatch => ({
  refreshJobs: async () => {
    const data = await api.Jobs.getAll();
    dispatch({ type: JOBS_LOADED, payload: { data } });
  }
});

export default connect(null, mapDispatchToProps)(CreateJob);

Option B: Using Redux Hooks (Modern & Cleaner)

If you're using Redux v7.1+, use useDispatch for a simpler approach:

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

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

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

  const handleSubmit = async e => {
    e.preventDefault();
    try {
      await api.Jobs.create(state);
      // Fetch and dispatch the latest jobs
      const data = await api.Jobs.getAll();
      dispatch({ type: JOBS_LOADED, payload: { data } });
      setState({ jobName: '', creator: '' });
    } 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;

Solution 2: Add the New Job Directly to Redux (More Efficient)

Instead of re-fetching all jobs (which is unnecessary), we can add the newly created job directly to our Redux store. This saves an API call and is faster.

  1. Add a new action type:

    // ActionTypes.js
    export const JOBS_LOADED = 'JOBS_LOADED';
    export const JOB_ADDED = 'JOB_ADDED';
    
  2. Update the reducer to handle the new action:

    // JobsReducer.js
    import { JOBS_LOADED, JOB_ADDED } from './ActionTypes';
    
    export default (state = {teams: []}, action) => {
      switch (action.type) {
        case JOBS_LOADED:
          return {
            ...state,
            teams: action.payload.data,
          };
        case JOB_ADDED:
          // Add the new job to the existing list
          return {
            ...state,
            teams: [...state.teams, action.payload.job],
          };
        default:
          return state;
      }
    };
    
  3. Dispatch the new action in CreateJob:

    const handleSubmit = async e => {
      e.preventDefault();
      try {
        // Assume your API returns the full created job (with jobId and other backend-generated fields)
        const newJob = await api.Jobs.create(state);
        // Dispatch the action to add the job to the store
        dispatch({ type: JOB_ADDED, payload: { job: newJob } });
        setState({ jobName: '', creator: '' });
      } catch (err) {
        console.error(err);
      }
    }
    

Final Notes

  • Naming Consistency: I'd recommend renaming teams to jobs in your reducer (since your app is job-focused) — it'll make your code easier to follow.
  • Choose the Right Solution: Solution 1 is great for beginners because it's simple and relies on logic you already have. Solution 2 is better for performance, especially if your job list gets large.

内容的提问来源于stack exchange,提问作者Jose the hose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:54:06