TypeError: dispatch is not a function in my thunks

TypeError: dispatch is not a function in my thunks

我有错误:

TypeError: dispatch is not a function

在这行代码中dispatch(addNewNote(response.data.message));

我不知道为什么会发生这个错误,因为我在 thunks.js 文件中的其他函数中有其他调度工作正常。

我真的需要帮助,如有任何建议,我将不胜感激。

请考虑以下代码:

binnacleReducer.js

   import { ADD_NEW_NOTE } from "../Actions/binnacleActions";

    export const binnacleNotesReducer = (state = [], action) => {
     const { type, payload } = action;
     switch (type) {

    case ADD_NEW_NOTE:
      const { binnacleNote } = payload;
       return state.concat(binnacleNote);
      default:
       return state;
  }
};

binnacleActions.js

//Action creators and actions

    export const ADD_NEW_NOTE = "ADD_NEW_NOTE";
    export const addNewNote = (binnacleNote) => ({
     type: ADD_NEW_NOTE,
     payload: {
      binnacleNote,
     },
    });

thunks.js

import axios from "axios";
import { loginSuccess, loginFailed } from "../Actions/authActions";
import {
  setOwnerSetup,
  setSuperSetup,
  loadBinnacleNotes,
  binnacleNoteReview,
  addNewNote,
} from "../Actions/binnacleActions";

export const addBinnacleNote = (
  binnacle,
  noteNumber,
  binnacleNote,
  responsible,
  file
) => async (dispatch, getState) => {
  try {
    const bodyToSend = new FormData();
    bodyToSend.append("binnacle", binnacle);
    bodyToSend.append("binnacleNote", binnacleNote);
    bodyToSend.append("noteNumber", noteNumber);
    bodyToSend.append("responsible", responsible);

    if (file) {
      for (let x = 0; x < file.length; x++) {
        bodyToSend.append(`file[${x}]`, file[x]);
      }
    }

    const response = await axios.post(
      "http://localhost:5000/addBinnacleNote",
      bodyToSend,
      {
        headers: {
          "Content-Type": "application/json",
        },
      }
    );
    dispatch(addNewNote(response.data.message));
  } catch (e) {
    alert("Thunk error in addNote: " + e);
  }
};

编辑:

BinnacleForm.js

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { addBinnacleNote } from "../../Store/Thunks/thunks";

import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import TextField from "@material-ui/core/TextField";
import Container from "@material-ui/core/Container";
import { Button } from "@material-ui/core";
import AccordionTest from "./AccordionTest";

var noteNumber;

function BinnacleForm({ authReducer, binnacleNotesReducer }) {
  const [binnacleNote, setBinnacleNote] = useState(null);
  const [file, setFile] = useState(null);
  const responsible = authReducer.role;
  const binnacle = authReducer.binnacle;

  const setBinnacleId = () => {
    if (binnacleNotesReducer !== [] || binnacleNotesReducer.length === 0) {
      noteNumber = 1;
    } else {
      noteNumber = binnacleNotesReducer[binnacleNotesReducer.length - 1].id + 1;
    }
  };

  setBinnacleId();

  return (
    <React.Fragment>
      <Container maxWidth="md">
        <Typography variant="h6" gutterBottom>
          Agregar Nota
        </Typography>
        {/* <AccordionTest /> */}
        <Grid container spacing={3}>
          <Grid item xs={12} sm={9}>
            <TextField
              required
              id="binnacle_note"
              name="binnacle_note"
              fullWidth
              autoComplete="given-name"
              helperText="Nota"
              onChange={(e) => setBinnacleNote(e.target.value)}
            />
          </Grid>
          <Grid item xs={12} sm={3}>
            <Button variant="contained" component="label">
              Adjuntar Archivo
              <input
                onChange={(e) => setFile(e.target.files)}
                type="file"
                hidden
                multiple
              />
            </Button>
          </Grid>
          <Button
            variant="contained"
            color="primary"
            onClick={addBinnacleNote(
              binnacle,
              noteNumber,
              binnacleNote,
              responsible,
              file
            )}
          >
            Agregar Nota
          </Button>
        </Grid>
      </Container>
    </React.Fragment>
  );
}

const mapStateToProps = (state) => ({
  binnacleReducer: state.binnacleReducer,
  authReducer: state.authReducer,
  binnacleNotesReducer: state.binnacleNotesReducer.binnacleNotes,
});

const mapDispatchToProps = (dispatch) => ({
  addBinnacleNote: (binnacle, binnacleNote, responsible) =>
    dispatch(addBinnacleNote(binnacle, binnacleNote, responsible)),
});

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

编辑 2:

BinnacleForm.js

import React, { useEffect } from "react";
import { connect } from "react-redux";
import SetupBinnacleSuper from "../Binnacle/SetupBinnacleSuper";
import SetupBinnacleOwner from "../Binnacle/SetupBinnacleOwner";
import {
  getBinnacleStatus,
  getBinnacleStatusBySuper,
} from "../../Store/Thunks/thunks";
import BinnacleNotesList from "../Binnacle/BinnacleNotesList";

const Binnacle = ({
  authReducer,
  binnacleReducer,
  getBinnacleStatus,
  getBinnacleStatusBySuper,
}) => {
  const binnacle = authReducer.binnacle;

  const renderConditionaly = () => {
    if (authReducer.role == "owner" && binnacleReducer.binnacleIsActive == 0) {
      return <SetupBinnacleOwner />;
    } else if (
      authReducer.role == "owner" &&
      binnacleReducer.binnacleIsActive == 1
    ) {
      console.log("If Owner");
      return <div>Owner</div>;
    } else if (
      authReducer.role == "super" &&
      binnacleReducer.binnacleIsActiveBySuper == 0
    ) {
      return <SetupBinnacleSuper />;
    } else if (
      authReducer.role == "super" &&
      binnacleReducer.binnacleIsActiveBySuper == 1
    ) {
      return <BinnacleNotesList />;
    } else if (authReducer.role == "dro") {
      return <BinnacleNotesList />;
    } else if (authReducer.role == "constructor") {
      return <BinnacleNotesList />;
    }
  };

  useEffect(() => {
    getBinnacleStatus(binnacle);
    getBinnacleStatusBySuper(binnacle);
  }, []);

  return (
    <div>
      <h2>Bienvenido {authReducer.email}</h2>
      {renderConditionaly()}
    </div>
  );
};

const mapStateToProps = (state) => ({
  authReducer: state.authReducer,
  binnacleReducer: state.binnacleReducer,
});

const mapDispatchToProps = (dispatch, getState) => ({
  getBinnacleStatus: (binnacle) => dispatch(getBinnacleStatus(binnacle)),
  getBinnacleStatusBySuper: (binnacle) =>
    dispatch(getBinnacleStatusBySuper(binnacle)),
});

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

binnacleReducer.js

export const binnacleReducer = (state = [], action) => {
  const { type, payload } = action;

  switch (type) {
    case SET_OWNER_SETUP:
      const { binnacleIsActive } = payload;
      return {
        ...state,
        binnacleIsActive,
      };
    case SET_SUPER_SETUP:
      const { binnacleIsActiveBySuper } = payload;
      return {
        ...state,
        binnacleIsActiveBySuper,
      };
    default:
      return state;
  }
};

binnacleActions.js

export const SET_SUPER_SETUP = "SET_SUPER_SETUP";
export const setSuperSetup = (binnacleIsActiveBySuper) => ({
  type: SET_SUPER_SETUP,
  payload: {
    binnacleIsActiveBySuper,
  },
});

thunks.js

import axios from "axios";
import { loginSuccess, loginFailed } from "../Actions/authActions";
import {
  setOwnerSetup,
  setSuperSetup,
  loadBinnacleNotes,
  binnacleNoteReview,
  addNewNote,
} from "../Actions/binnacleActions";

export const getBinnacleStatusBySuper = (binnacle) => async (
  dispatch,
  getState
) => {
  try {
    const response = await axios.get(
      `http://localhost:5000/getBinnacleStatusBySuper?binnacle=${binnacle}`
    );
    dispatch(
      setSuperSetup(response.data.binnacleIsActiveBySuper.is_active_by_super)
    );
  } catch (e) {
    alert(e);
  }
};

问题是您没有调度由 addBinnacleNote 编辑的 return 操作。 onClick 属性应该是一个函数。

您已经将 mapDispatchToProps 函数定义为 return 一个 addBinnacleNote prop 来分派操作,但您没有在组件内部使用它。您正在调用导入的 addBinnacleNote 函数。有几种方法可以解决它。您可以删除 mapDispatchToProps 函数并使用 useDispatch 访问 dispatch 函数并在 onClick 处理程序中调度操作。

import { useDispatch } from 'react-redux'

const dispatch = useDispatch()
<Button
  variant="contained"
  color="primary"
  onClick={() =>
    dispatch(
      addBinnacleNote(binnacle, noteNumber, binnacleNote, responsible, file)
    )
  }
>
  Agregar Nota
</Button>

或者您可以在 onClick 处理程序中使用 addBinnacleNote 道具。