【问题标题】:How to use async await inside an event?如何在事件中使用异步等待?
【发布时间】:2019-10-29 01:13:36
【问题描述】:

这是我的游戏介绍页面的代码。它有一个提交按钮和用于用户名输入的文本框。当用户写下他的名字并点击提交按钮时,代码会将名字发布到一个 json 文件中,然后从 json 文件中获取所有数据以将其发送到排行榜。那行得通。但它没有得到最后发布的用户名。我尝试向 getUserInfo() 添加一个异步等待函数(console.log("userinfo: " + this.state.usersInfo) 在我添加异步等待时显示每个对象)但游戏页面没有显示,并且我在控制台上收到一个奇怪的错误:Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the method `preventDefault` on a released/nullified synthetic event. This is a no-op function. If you must keep the original synthetic event around, use event.persist(). 我确实尝试使用事件.persist() 已经,但游戏页面仍然没有出现。有什么帮助吗?

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      page: "game",
      showInicio: false,
      userInput:"",
      usersInfo:[],
      dataPosted: false,
      head:[],
      isNew: true,
    };
    //function needs to be bound to be used in child component (NavBar.js)
    this.changePage = this.changePage.bind(this);

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  changePage(page) {

    this.setState({
      page

    });
  }

  handleChange(event) {
    this.setState({userInput: event.target.value});

  }

  async handleSubmit(event) {
    this.postUserInfo(); 
    await this.getUserInfo();
    console.log("userinfo: " + this.state.usersInfo)
    alert('Username was submitted: ' + this.state.userInput);
    event.preventDefault();
    this.setState({  
      showInicio: !this.state.showInicio 
 }); 

  }


   postUserInfo(){
    fetch("http://localhost:8080/api/users" , {
      method: "post" ,
      mode: "cors",
      headers: {
        "Content-type": "application/json",
      },
      body:JSON.stringify({username:this.state.userInput,bestattempts:0, besttime:0 })
    })

    .then((res) => res.json()) 
    .then((data => {
      console.log(data);  
      this.setState({ dataPosted: true });
    }))
    .catch((error) => {
    console.log(error);
  });
  } 

  async getUserInfo() {
    return fetch("http://localhost:8080/api/users" , {mode: "cors"})
    .then((res) => res.json())
    .then((data => {
      this.setState({ usersInfo: data})

    const _head = {
      id: "ID",
      username: "Username",
      bestattempts: "Best Attempts", 
      besttime: "Best Time",
    }
    this.setState({head:_head})}))
  }     


  render() {
    if (this.state.showInicio === false){
    return (
      <div>
      <div className="inicio">  
        <h1> Memory game </h1> 
      </div>
      <div className="iniciodentro">
        <form onSubmit={this.handleSubmit}>
        <label>
          Enter your username:
        <input type="text" value={this.state.userInput} onChange={this.handleChange} required/>
        </label>
        <input type="submit" value="Submit" />
      </form>
      </div> 
      </div>
     );
    }else{
    const { page } = this.state;
    return (
      <div className="App">
        <NavBar page={page} changePage={this.changePage} />
        <div className="App-header">
          {page === "game" && <Game dataPosted={this.state.dataPosted} username = {this.state.userInput} isNew={this.state.isNew}/>}
          {page === "leaderboard" && <LeaderBoard usersInfo={this.state.usersInfo} head={this.state.head}/>}
        </div>
      </div>
    );
  }
}
}

export default App;

【问题讨论】:

  • 这个link的可能副本。
  • 你会想要在任何 await 之前 preventDefault - 否则你不会及时阻止默认 - 所以,只需将 preventDefault before 任何等待,然后你的代码应该没问题

标签: javascript node.js reactjs


【解决方案1】:

简单地说,我建议 我建议把你的handleSubmit 变成这个:

handleSubmit(event) {
    event.preventDefault();

    this.postUserInfo().then(()=>{

        return this.getUserInfo();

    }).then(()=>{

        console.log("userinfo: " + this.state.usersInfo)
        alert('Username was submitted: ' + this.state.userInput);
        this.setState({
            showInicio: !this.state.showInicio
        });

    });
}

并在您的 postUserInfogetUserInfo 方法中执行此操作:

postUserInfo(){
    return fetch("http://localhost:8080/api/users", {
        method: "post",
        mode: "cors",
        headers: {
            "Content-type": "application/json",
        },
        body: JSON.stringify({ username: this.state.userInput, bestattempts: 0, besttime: 0 })
    })
    .then((res) => res.json())
    .then(data => {
        console.log(data);
        this.setState({ dataPosted: true });
    })
    .catch((error) => {
        console.log(error);
    })

}
getUserInfo() {
    return fetch("http://localhost:8080/api/users", { mode: "cors" })
        .then((res) => res.json())
        .then(data => { //you had a syntax mistake here: (data
            this.setState({ usersInfo: data })

            const _head = {
                id: "ID",
                username: "Username",
                bestattempts: "Best Attempts",
                besttime: "Best Time",
            }
            this.setState({ head: _head })
        })
}

没有必要使用 async/await,因为 fetch API 已经使用了 Promise。

您收到奇怪错误的原因可能是因为您试图在异步函数中阻止Default()。 是因为 preventDefault 是在第一次等待之后执行的

感谢Bravo 澄清。

【讨论】:

  • the weird error may have been because you were trying to preventDefault() inside of an async function - 不,这仅仅是因为在第一次等待之后执行 preventDefault - 否则 OP 的代码很好
  • 谢谢Bravo,我修正了我的答案。尽管我会争辩说,因为他没有等待 postUserInfo (),所以他的代码仍然无法按预期工作,因为在他执行 getUserInfo() 之前,他的发布数据不会保存到服务器
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-20
  • 1970-01-01
  • 2018-12-27
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多