import React from 'react'
import { ToptipsManager } from '../utils/Toptips'
import './Register.scss'
export default class Register extends React.Component {
constructor(props) {
super(props)
console.log(props)
this.state = {
noGetMessageDisplay: 'none',
phone: this.props.phone || '',
mobile_code: this.props.mobile_code || '',
count: 60,
liked: true
}
this.handleClick = this.handleClick.bind(this)
this.handleInputChange = this.handleInputChange.bind(this)
}
noGetMessage = e => {
this.getAudioRequest()
}
// 获取语音验证码
getAudioRequest() {
if(this.state.phone === '') {
ToptipsManager.warn("请先输入手机号")
return
} else if(!(/^1[34578]\d{9}$/.test(this.state.phone))) {
ToptipsManager.warn("手机号格式不正确")
return
} else {
alert("处理语音验证码ajax api.......")
}
}
//获取短信验证码
handleClick = () => {
if (!this.state.liked) {
return
}
if(this.state.phone === '') {
ToptipsManager.warn("请先输入手机号")
return
} else if(!(/^1[34578]\d{9}$/.test(this.state.phone))) {
ToptipsManager.warn("手机号格式不正确")
return
} else {
console.log("点击获取验证码")
this.setState({
noGetMessageDisplay: 'block'
})
console.log(this.state.liked)
let count = this.state.count
console.log(count)
const timer = setInterval(() => {
this.setState({ count: (count--), liked: false }, () => {
if (count === 0) {
clearInterval(timer);
this.setState({
liked: true ,
count: 60
})
}
});
}, 1000);
}
}
handleInputChange(event) {
const target = event.target;
const name = target.name;
const value = target.value;
this.setState({
[name]: value
}, () => {
// console.log(this.state)
})
}
render() {
return (
<div className="user_register">
<div className="register_box" style={{ display: this.state.isRegLoginContainer }}>
<div className="login_content" style={{ display: this.state.isLoginContainer }}>
<div className="phone_number">
<p>手机号</p>
<input type="tel" placeholder="请输入手机号" maxLength="11" name="phone" value={this.state.phone} onChange={this.handleInputChange} />
</div>
<div className="vscode_message">
<div className="vscode_title">
<span onClick={this.noGetMessage} style={{ display: this.state.noGetMessageDisplay }}>没收到验证码?</span>
<p>验证码</p>
</div>
<div className="get_receive_vscode">
<p onClick={this.handleClick}>
{
this.state.liked ?
<span>获取验证码</span>
:
<span className="count_second">{this.state.count + 's'}</span>
}
</p>
<input type="tel" placeholder="请输入验证码" maxLength="4" name="mobile_code" value={this.state.mobile_code} onChange={this.handleInputChange} />
</div>
</div>
</div>
</div>
</div>
)
}
}
// 这里我把css的代码也贴进来吧.上次有网友说liked一直是true的状态, 就是因为他们没处理css的部分.
.user_register {
height: 100vh;
position: relative;
background: #fff;
.register_box {
width: 80%;
margin: 0 auto 20px;
padding-top: 50px;
.login_content {
input {
width: 90%;
margin: 0 auto;
display: block;
height: 35px;
border: 1px solid #333;
outline: none;
font-size: 15px;
border-radius: 5px;
-webkit-appearance: none;
border: none;
margin-left: 0px;
}
input::-webkit-input-placeholder {
color: #ccc;
font-weight: 300;
font-size: 16px;
}
input::-moz-placeholder {
color: #ccc;
font-weight: 300;
font-size: 16px;
}
input::-moz-placeholder {
color: #ccc;
font-weight: 300;
font-size: 16px;
}
input:-ms-input-placeholder {
color: #ccc;
font-weight: 300;
font-size: 16px;
}
}
.phone_number {
width: 90%;
border-bottom: 1px solid #eee;
margin-left: 18px;
p {
color: #666;
font-weight: 500;
background: url(../../../assets/images/icon_app.png) no-repeat;
background-size: 18px;
padding-left: 22px;
background-position: left center;
}
}
.vscode_message {
width: 90%;
border-bottom: 1px solid #eee;
margin-left: 18px;
padding-top: 20px;
.vscode_title {
span {
float: right;
color: #59aaff;
font-size: 13px;
font-weight: 300;
}
p {
color: #666;
font-weight: 500;
background: url(../../../assets/images/icon-comment.png) no-repeat;
background-size: 18px;
padding-left: 22px;
background-position: left center;
}
}
.get_receive_vscode {
p {
display: block;
padding: 4px 10px;
border: 1px solid #ddd;
border-radius: 50px;
font-size: 13px;
float: right;
text-align: center;
width: 90px;
.count_second {
color: #999;
}
}
input {
width: 50%;
}
}
}
}
}
注:
liked:属性值“false/true“来控制“获取验证码/秒数倒计时“文案部分
count:控制秒数倒计时
注:
我看评论里有小伙伴对下面这行代码,不是很理解. 这里我解释一下:
const timer = setInterval(() => {
this.setState({
count: (count--), liked: false
}, () => {
if (count === 0) {
clearInterval(timer);
this.setState({
liked: true ,
count: 60
})
}
});
}, 1000);
想要体现的意思就是, 当count的状态更改之后, 当count依次倒数的时候我们要取用的并不是这个事件的值,而是要更改过后的state(状态)值,也就是当前情况下count为0的值。
如果要在setState方法后,直接取用更动后的state值,正确的使用方式,在官方文件中的说明,需要利用setState的第二传参,传入一个回调(callback)函式,改为像下面这样的代码你应该就可以很明白的看出来了:
this.setState({
count: (count--)
}, () => {
// TODO
})
为什么一定要这样作的主要原因是:
setState这个方法,它在React中的执行行为可以认为"异步的"
当然,如果你不想通过callback来做, 当然也是可以的,把callback提出去,依然可以拿到count变化后的state值.