【问题标题】:Refactoring using Async and await in React?在 React 中使用异步和等待进行重构?
【发布时间】:2020-05-15 02:15:48
【问题描述】:

来自 Java 背景的我(非常)新反应。我正在尝试重构一些现有代码以使用异步和等待。

错误出现在我的渲染函数()(用 ***** 突出显示)之前,并且我得到一个“/src/App.js: Unexpected token, expected”,错误和无法终生弄清楚发生了什么。我试过弄乱 } ) 和 ; 并不能完全追踪它。感谢任何帮助。

import React, { Component } from "react";
import { FixedSizeGrid } from "react-window";

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      specialties: [],
      isLoaded: false,
      error: null
    };
  }

  async componentDidMount() {
    const response = await fetch (url)
    .then(response => response.json())
    .then(body => {
      const specialties = body.data.specialties;
      return specialties;
    })
    .then(specialties => {
      return specialties.map(({ _id, name }) => {
        return [_id, name];
      })


      .then(transformed => {
        this.setState({
          specialties: transformed,
          isLoaded: true,
          error: null
        });
      })

      .catch(error => {
        this.setState({
          specialties: [],
          isLoaded: true,
          error: error
         });
      });
    }




  render() {***********************here 
    if (this.state.error) {
      return <span style={{ color: "red" }}>{this.state.error.message}</span>;
    }

    if (!this.state.isLoaded) {
      return "Loading...";
    }

    const ITEM_HEIGHT = 35;

    return (
      <FixedSizeGrid
        columnWidth={300}
        rowHeight={35}
        itemData={this.state.specialties}
        height={ITEM_HEIGHT * this.state.specialties.length}
        width={600}
        itemSize={() => ITEM_HEIGHT}
        columnCount={2}
        rowCount={this.state.specialties.length}
      >
        {SpecialtyYielder}
      </FixedSizeGrid>
    );
  }
}

const SpecialtyYielder = ({ columnIndex, rowIndex, data, style }) => {
  return (
    <div
      style={{
        ...style,
        backgroundColor:
          (rowIndex + columnIndex) % 2 ? "beige" : "antiquewhite",
        display: "flex",
        alignItems: "center",
        justifyContent: "center"
      }}
    >
      {data[rowIndex][columnIndex]}
    </div>
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【问题讨论】:

  • 在执行 async/await 时不要使用 .then,这就是重点。你把它当作同步代码来对待
  • Ya.. 如果您不使用 fetch 的响应,为什么还要在那里使用 await fetch? await 实际上什么都不做

标签: javascript reactjs


【解决方案1】:

您缺少括号和括号:

  async componentDidMount() {
    const response = await fetch (url)
    .then(response => response.json())
    .then(body => {
      const specialties = body.data.specialties;
      return specialties;
    })
    .then(specialties => {
      return specialties.map(({ _id, name }) => {
        return [_id, name];
      })
    })  // missing closing bracket and paren


      .then(transformed => {
        this.setState({
          specialties: transformed,
          isLoaded: true,
          error: null
        });
      })

      .catch(error => {
        this.setState({
          specialties: [],
          isLoaded: true,
          error: error
         });
      });
    }

异步/等待
基本上在你使用then 的所有地方,你都可以使用await,但是这样你就不需要一堆回调并且逻辑就像同步代码:

  async componentDidMount() {
    try {
      const response = await fetch (url)
      const body = await response.json()
      const specialties = body.data.specialties;
      const transformed = specialties.map(({ _id, name }) => {
        return [_id, name]
      })
      this.setState({
          specialties: transformed,
          isLoaded: true,
          error: null
      })
    }
    catch(error) {
        this.setState({
          specialties: [],
          isLoaded: true,
          error: error
        })
    }
  }

【讨论】:

  • 非常感谢修复它。你能澄清一下“const specialties = body.data.specialties;”是什么吗?在做什么?
  • 当然,它正在检索包含在 { data: { specialties: (value) } } 中的 json 值,该值之前已提取到 body 变量中。如果是我,我可能会将专业和转换后的 .map 压缩成一行(因为它基本上就像一次通过理解),然后使用 { specialities, isLoaded: true ...。但这对您来说可能更具可读性,而且肯定没有任何问题。
【解决方案2】:

看起来您可能需要更好的文本编辑器;)。它在您的componentDidMount 中。最后你错过了一个),关闭你的.then块,然后用另一个花括号关闭componentDidMount

  async componentDidMount() {
    const response = await fetch (url)
    .then(response => response.json())
    .then(body => {
      const specialties = body.data.specialties;
      return specialties;
    })
    .then(specialties => {
      return specialties.map(({ _id, name }) => {
        return [_id, name];
      })


      .then(transformed => {
        this.setState({
          specialties: transformed,
          isLoaded: true,
          error: null
        });
      })

      .catch(error => {
        this.setState({
          specialties: [],
          isLoaded: true,
          error: error
         });
      });
    })
}

这解决了您的语法错误。您提出问题的方式看起来好像您认为它的“解决方案”是使用async/await。您显然仍然可以进行重构。您是否还有兴趣探索 async/await?

【讨论】:

    【解决方案3】:

    您在componentDidMount 方法中缺少})

    import React, { Component } from "react";
    import { FixedSizeGrid } from "react-window";
    
    export default class App extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          specialties: [],
          isLoaded: false,
          error: null
        };
      }
    
      async componentDidMount() {
        const response = await fetch (url)
        .then(response => response.json())
        .then(body => {
          const specialties = body.data.specialties;
          return specialties;
        })
        .then(specialties => {
          return specialties.map(({ _id, name }) => {
            return [_id, name];
          })
    
    
          .then(transformed => {
            this.setState({
              specialties: transformed,
              isLoaded: true,
              error: null
            });
          })
    
          .catch(error => {
            this.setState({
              specialties: [],
              isLoaded: true,
              error: error
             });
          });
        })}
    
    
    
      render() {
    
    
    
    
        const ITEM_HEIGHT = 35;
    
        return (
          <FixedSizeGrid
            columnWidth={300}
            rowHeight={35}
            itemData={this.state.specialties}
            height={ITEM_HEIGHT * this.state.specialties.length}
            width={600}
            itemSize={() => ITEM_HEIGHT}
            columnCount={2}
            rowCount={this.state.specialties.length}
          >
            {SpecialtyYielder}
          </FixedSizeGrid>
        );
      }
    }
    
    const SpecialtyYielder = ({ columnIndex, rowIndex, data, style }) => {
      return (
        <div
          style={{
            ...style,
            backgroundColor:
              (rowIndex + columnIndex) % 2 ? "beige" : "antiquewhite",
            display: "flex",
            alignItems: "center",
            justifyContent: "center"
          }}
        >
          {data[rowIndex][columnIndex]}
        </div>
      );
    };
    

    【讨论】:

      猜你喜欢
      • 2018-04-20
      • 1970-01-01
      • 1970-01-01
      • 2020-09-11
      • 1970-01-01
      • 2014-11-22
      • 2023-03-30
      • 2019-07-02
      • 1970-01-01
      相关资源
      最近更新 更多