【问题标题】:React: Unhandled Rejection (TypeError): Cannot read property 'data' of undefined反应:未处理的拒绝(TypeError):无法读取未定义的属性“数据”
【发布时间】:2020-11-27 14:57:02
【问题描述】:

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

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

数据仍在提交到 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,
      };
  }
}

【问题讨论】:

  • API.post 是否返回任何内容?它会返回一个承诺或API.post("/clients/invoice/", invoice).then 会导致错误,但承诺会解决任何问题吗?
  • API 与 api 不同,JavaScript 区分大小写。您是否导出 api 并将其作为 API 导入? API.post 函数是什么?
  • 那我猜是请求失败并且err.response.data导致错误,你能在网络选项卡中看到请求,看看它是否有数据失败?
  • ADD_INVOICE_DATA 被调度并更新状态。所以err.response.data没有被触发。
  • 发布的代码中可能出现Cannot read property 'data' of undefined/ 错误的唯一两个地方是payload: res.data,err.response.data 也许您可以发布发生错误的代码?

标签: reactjs api redux react-redux


【解决方案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))
);

【讨论】:

    猜你喜欢
    • 2019-03-25
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2017-12-26
    • 2021-05-06
    • 2019-04-07
    • 2021-08-16
    相关资源
    最近更新 更多