反应:未处理的拒绝(TypeError):无法读取未定义的属性“数据”

时间:2020-08-07 09:26:48

标签: reactjs api redux react-redux

在我的react / redux应用程序中,每当我将表单数据传递给POST api时,我都会报错

未处理的拒绝(TypeError):无法读取未定义的属性'data'/

数据仍在提交到Django后端,因为当我在后端检查数据时,我可以确认在表单中输入的数据已提交并保存。但是,我认为这是错误的前端。 我想念的是什么?

表单组件

class FormInvoice extends Component {
  state = {
    invoiceOwner: "",
    product: "",
    quantity: "",
    mode: "",
    status: "",
    payment_made: "",
  };

  static propTypes = {
    addInvoiceData: PropTypes.func.isRequired,
  };

  onChange = (e) =>
    this.setState({
      [e.target.name]: e.target.value,
    });

  onSubmit = (e) => {
    e.preventDefault();
    const {
      invoiceOwner,
      product,
      quantity,
      mode,
      status,
      payment_made,
    } = this.state;
    const invoice = {
      invoiceOwner,
      product,
      quantity,
      mode,
      status,
      payment_made,
    };
    this.props.addInvoiceData(invoice); <=== Action for passing data to POST api
  };
  render() {
    const {
      invoiceOwner,
      product,
      quantity,
      mode,
      status,
      payment_made,
    } = this.state;
    return (
      <div className="App container">
        <Modal isOpen={this.props.newInvoiceModal} scrollable={true}>
          <ModalHeader toggle={this.props.toggleModal}>Add Invoice</ModalHeader>
          <ModalBody>
            <FormGroup>
              <Label for="title">Name</Label>
              <Input
                name="invoiceOwner"
                value={invoiceOwner}
                onChange={this.onChange}
              />
            </FormGroup>
            <FormGroup>
              <Label for="title">Product</Label>
              <Input name="product" value={product} onChange={this.onChange} />
            </FormGroup>

            <FormGroup>
              <Label for="title">Quantity</Label>
              <Input
                name="quantity"
                value={quantity}
                onChange={this.onChange}
              />
            </FormGroup>
            <FormGroup>
              <Label for="title">Mode</Label>
              <Input name="mode" value={mode} onChange={this.onChange} />
            </FormGroup>
            <FormGroup>
              <Label for="title">Status</Label>
              <Input name="status" value={status} onChange={this.onChange} />
            </FormGroup>
            <FormGroup>
              <Label for="title">Paid</Label>
              <Input
                name="payment_made"
                value={payment_made}
                onChange={this.onChange}
              />
            </FormGroup>
          </ModalBody>
          <ModalFooter>
            <button onClick={this.onSubmit} className="btn btn-primary">
              Submit
            </button>{" "}
            <Button color="secondary" onClick={this.props.toggleModal}>
              Cancel
            </Button>
          </ModalFooter>
        </Modal>
      </div>
    );
  }
}

export default connect(null, { addInvoiceData })(FormInvoice);

Redux 部分

// API
const api = Axios.create({
  baseURL: "http://localhost:8000/api",
  timeout: 30000,
  headers: {
    "Content-Type": "application/json",
    "Accept": "application/json",
  },
});

api.interceptors.request.use(
  (config) => {
    if (localStorage.getItem("access")) {
      config.headers.Authorization = `JWT ${localStorage.getItem("access")}`;
    }

    return config;
  },
  (error) => Promise.reject(error)
);
export default api;

// ADD INVOICE DATA
import API from "../api"

export const addInvoiceData = (invoice) => async (dispatch) => {
  await API.post("/clients/invoice/", invoice)
    .then((res) => {
      dispatch(createMessage({ addInvoiceData: "Invoice detail added" }));
      dispatch({
        type: ADD_INVOICE_DATA,
        payload: res.data,
      });
      dispatch({
        type: TOGGLE_MODAL,
      });
    })
    .catch((err) =>
      dispatch(returnErrors(err.response.data, err.response.status))
    );
};

//Reducer
const initialState = {
  invoiceData: [],
  newInvoiceModal: false,
};

export default function (state = initialState, action) {
  switch (action.type) {
    case GET_INVOICE_DATA:
      return {
        ...state,
        invoiceData: action.payload,
      };

    case ADD_INVOICE_DATA:
      return {
        ...state,
        invoiceData: action.payload,
      };
  }
}

1 个答案:

答案 0 :(得分:1)

问题出在这里:

    .then((res) => {
      dispatch(createMessage({ addInvoiceData: "Invoice detail added" }));
      ...
    })
    .catch((err) =>
      // not every err looks like : err.response.data
      dispatch(returnErrors(err.response.data, err.response.status))
    );

如果在第一个块中发生任何异常,则catch尝试对其进行处理,并调用err.response.data。并且由于err.responseundefined,因此您会收到Cannot read property 'data' of undefined错误。

因此,在第一个块中添加一个try catch语句以立即捕获第一个块中的异常:

.then((res) => {
  try{
    dispatch(createMessage({ addInvoiceData: "Invoice detail added" }));
    ...
  }
  catch(e) {
    console.log(res, e)
  }
}).catch((err) =>
  dispatch(returnErrors(err.response.data, err.response.status))
);