react redux asyc tasks with rest api



在我的新项目注册中,用户必须通过 3 步

  1. 用户输入电话号码
  2. 使用短信验证码验证电话号码
  3. 完整的个人信息

用户注册使用 REST API 工作 第一个 API 发布电话号码并返回 4 位代码和 Redux 中的代码存储 然后用户必须插入 4 位数字,如果它正确第二个 API 发布电话号码和数字,如果用户电话号码未注册之前返回空字符串,否则返回令牌并存储在 Redux 中 当我收到响应时,我想检查它是否是空字符串用户转到步骤 3 否则现在显示错误消息,我这样做了 设置超时,但这不是正确的方式,我正在寻找正确的方式

这是我的代码:

// check user insert correct 4 digit
if (this.state.smsCode === this.props.smsCode) {
// Post phone number and sms code with redux action
this.props.setUserToken(this.state.phoneNumber, this.state.smsCode);
setTimeout(() => {
if (this.props.userToken === "") {
// go to next step
} else {
// show error
}
}, 4000);
}

快速注释然后是一个示例实现

JS最佳实践

使用这样的 setTimeout 是一种糟糕的 JS 实践。这表明你对异步/多线程语言如何工作和应该实现没有想象力。如果服务器受到限制并且需要 5000 毫秒才能返回响应,您将错过它。相反,如果需要 10 毫秒,您的用户将无缘无故等待 3990 毫秒。setUserToken 应该接受回调作为参数或返回一个承诺,从而允许异步代码执行。即

this.props.setUserToken(this.state.phoneNumber, this.state.smsCode)
.then(res => {/*move on*/})
.catch(err => {/*display error*/})
// OR
this.props.setUserToken(
this.state.phoneNumber, 
this.state.smsCode, 
(res, err) => {
if(err) {
// set error
} else {
// move on
}
)

您可以在下面看到一个适用于您提出的要求的实现。它将呈现三个视图:电话号码输入窗体、代码提交窗体和经过验证的视图窗体。将您的服务器调用挂接到这个,它将起作用:

import React from 'react';
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
step: 'phone',
number: null,
error: undefined
}
this.requestCode = phoneNumber => {
// api request code here with phone number
/*
api.requestCode(phoneNumber, (res, err) => console.log(err ? 'FAIL' : 'WE DID IT!'))
*/
}
this.verifyCode = code => new Promise((resolve, reject) => {
// api request here submitting the code asynchronously
// in the async function triggered when the api responds, 
// either set an error or allow them through:
/*
api.verifyCode(code, (res, err) => {
if(err) {
reject(err)
} else {
resolve(res)
}
})
*/
})
this.submitPhoneNumber = e => {
const phoneNumber = this.refs.phoneInput.value
this.setState({
step: 'code',
number: phoneNumber
})
this.requestCode(phoneNumber)
}
this.submitCode = e => {
const code = this.refs.codeInput.value
this.verifyCode(code)
.then(res => this.setState({step: 'authenticated'}))
.catch(err => this.setState({error: err}))
}
}
renderInputPhone() {
return (
<div>
<form onSubmit={this.submitPhoneNumber}>
<div>Input phone number</div>
<input ref="phoneInput"></input>
<div>
<button type="submit">submit!</button>
</div>
<div>
<button onClick={e => this.requestCode(this.state.number)}>Resent code</button>
</div>
</form>
<div>
<button onClick={e => this.setState({step: 'phone'})}>back</button>
</div>
</div>
)
}
renderCodeInput() {
return (
<form onSubmit={this.submitCode}>
<div>Input sent code</div>
<input ref="codeInput" defaultValue={this.state.number}></input>
<div>
<button type="submit">submit!</button>
</div>
</form>
)
}
renderAutheticatedView() {
return (
<div>we're in</div>
)
}
render() {
return (
this.state.step === 'phone' ? this.renderInputPhone()
: this.state.step === 'code' ? this.renderCodeInput()
: this.state.step === 'authenticated' ? this.renderAutheticatedView()
: null
);
}
}

最新更新