首页 > 解决方案 > 从 React 中的函数更新状态

问题描述

我的应用程序有一个类组件。安装组件后,我需要运行一个函数getOrder来检查我们的数据库是否存在此类订单。如果找到,我需要使用订单中的数据更新状态。

函数getOrder在多个地方使用,所以我想将它移动到一个单独的文件中。

这是我现在拥有的:

class App extends React.Component {
  state = {
    data: {}
  }

  getOrder = async () => {
    axios.post('', {})
    .then(response => {
      console.log(response);
      if (response.data.result === true) {
        let result = JSON.parse(response.data.data);
        this.setState({data: result});
      } else {
        alert("Order is not found");
      }
    })
    .catch(error => console.log(error));
  };

  async componentDidMount() {
    await this.getOrder()
  }

  render() {
    return (</>);
  }
}

我想像这样将功能移到getOrder组件之外:

const getOrder = async () => {
  axios.post('', {})
  .then(response => {
    console.log(response);
    if (response.data.result === true) {
      let result = JSON.parse(response.data.data);
      this.setState({data: result});
    } else {
      alert("Order is not found");
    }
  })
  .catch(error => console.log(error));
};

class App extends React.Component {
  state = {
    data: {}
  }

  async componentDidMount() {
    await getOrder()
  }

  render() {
    return (</>);
  }
}

在这种情况下,如何从函数中更新 App 的状态getOrder

标签: javascriptreactjs

解决方案


简短的回答是:不要从组件外部更新状态。这会导致紧密耦合,从而难以扩展、重构和测试您的组件。


要重构这一点,您需要考虑代码的哪些部分与获取订单数据相关,哪些与呈现结果相关。例如,尽量不要让与传输相关的详细信息(HTTP 状态、正文解析等)泄漏到您的组件中,或者从您的服务中向用户显示内容。

此外,我通常会避免将async/await语法与.then/混合.catch- 至少在每个函数中你应该坚持一个或另一个。

这是重新排列它的一种方法,其中getOrder返回一个用解析的数据解析或拒绝并返回错误消息的承诺:

const getOrder = async () => {
  const response = await axios.post('', {});
  if (response.data.result) {
    return JSON.parse(response.data.data);
  }
  throw new Error("Order is not found");
};

现在该组件只处理显示该数据或错误:

class App extends React.Component {
  state = {
    data: {}
  }

  async componentDidMount() {
    try {
      const data = await getOrder();
      this.setState({ data });
    } catch(err) {
      alert(err);
    }
  }

  render() {
    return (</>);
  }
}

推荐阅读