粘貼到我的電子郵件後,我無法弄清爲什麼在文本框中複製它。在React Component的文本框中複製文本的粘貼
看來,當我粘貼,它正確地觸發handleEmailPaste
,但我也注意到,handleEmailPaste
也得到由過去那麼不知道爲什麼觸發。我猜粘貼是一種變化,所以在文本中粘貼可能會觸發這兩種功能。 如果我註釋掉handleEmailInput
中的代碼並粘貼一個值,它不會重複它。
我想我不知道處理這個問題的正確方法。對我來說似乎我確實需要兩個獨立的處理程序。請注意,我使用的是引導和控制它,我已經有了的onChange和onPaste集:
<FormControl
bsSize="small"
className="ft-username"
componentClass="input"
onPaste={this.props.handleEmailPaste}
onChange={this.props.handleEmailInput}
placeholder="Enter email"
style={{ width: 300}}
type="email"
value={this.props.email}
/>
LoginContainer
import { connect } from 'react-redux'
import React, { Component } from 'react'
const zxcvbn = require('zxcvbn'),
_ = require('lodash')
import * as AsyncActions from '../actions/Auth/AuthAsyncActions'
import Login from '../components/Login/Login'
class LoginContainer extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
errorMessage: '',
emailValidationState: null,
formIsValid: false,
formValidationState: null,
passwordValidationState: null,
passwordIsValid: null
}
this.handleEmailPaste = this.handleEmailPaste.bind(this)
this.handleEmailInput = this.handleEmailInput.bind(this)
this.handlePasswordInput = this.handlePasswordInput.bind(this)
this.handleLoginPressed = this.handleLoginPressed.bind(this)
this.resetFields = this.resetFields.bind(this)
this.validateForm = this.validateForm.bind(this)
this.validateEmail = this.validateEmail.bind(this)
this.validatePassword = this.validatePassword.bind(this)
}
handlePasswordInput(e) {
const password = e.target.value
this.setState({ password: password})
this.validatePassword()
}
handleEmailPaste(e){
console.log(`handleEmailPaste: ${e.clipboardData.getData('Text')}`)
const value = e.clipboardData.getData('Text')
this.setState({ email: value })
this.validateEmail(value)
}
handleEmailInput(e) {
this.setState({ email: e.target.value })
this.validateEmail()
}
async handleLoginPressed(e) {
e.preventDefault()
this.validateForm()
await this.props.authenticate(this.state.email, this.state.password)
if(this.props.isAuthenticated) {
this.props.history.push('/dashboard')
return
}
if(!this.props.isAuthenticated){
this.setState({
formValidationState: 'error',
errorMessage: this.state.formIsValid &&
'Your password and/or email is not associated with an active user'
})
if(this.state.email && this.state.password){this.resetFields()}
}
}
validateForm(){
this.validateEmail()
this.validatePassword()
this.setState({
formIsValid: (this.state.emailValidationState === 'success'
&& this.state.passwordValidationState === 'success')})
}
validatePassword(){
const password = zxcvbn(this.state.password)
if(password.score >=0){
this.setState({
passwordValidationState: 'error',
passwordHelpText: password.feedback.suggestions})
return
}
this.setState({
passwordValidationState: 'success',
passwordHelpText: null })
}
validateEmail(value){
if((!_.isEmpty(value)) || !_.isEmpty(this.state.email)) {
this.setState({
emailValidationState: 'success',
emailError: ''
})
return
}
this.setState({
emailValidationState: 'error',
emailError: 'please enter an email address'
})
}
resetFields(){
this.setState({
email: '',
emailError: '',
emailValidationState: null,
password: '',
passwordHelpText: '',
passwordValidationState: null })
}
render(){
return(
<div>
<Login
email={this.state.email}
emailError={this.state.emailError}
emailValidationState={this.state.emailValidationState}
errorMessage={this.state.errorMessage}
formValidationState={this.state.formValidationState}
handleEmailInput={this.handleEmailInput}
handleEmailPaste={this.handleEmailPaste}
handlePasswordInput={this.handlePasswordInput}
login={this.handleLoginPressed}
password={this.state.password}
passwordHelpText={this.state.passwordHelpText}
passwordValidationState={this.state.passwordValidationState}
/>
</div>
)
}
}
const mapStateToProps = state => ({
isAuthenticating: state.auth.isAuthenticating,
isAuthenticated: state.auth.isAuthenticated,
token: state.auth.token
})
export const mapDispatchToProps = {
authenticate: AsyncActions.authenticate
}
export { Login }
export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer)
登錄
import React, {Component} from 'react'
import LoginForm from './LoginForm'
export default class Login extends Component {
render(){
return (
<div>
<LoginForm
email={this.props.email}
emailError={this.props.emailError}
emailValidationState={this.props.emailValidationState}
errorMessage={this.props.errorMessage}
formValidationState={this.props.formValidationState}
handleEmailInput={this.props.handleEmailInput}
handleEmailPaste={this.props.handleEmailPaste}
handlePasswordInput={this.props.handlePasswordInput}
login={this.props.login}
password={this.props.password}
passwordHelpText={this.props.passwordHelpText}
passwordValidationState={this.props.passwordValidationState}
/>
</div>
)
}
}
LoginForm
import React, { Component } from 'react'
import {
Button,
ControlLabel,
HelpBlock,
FormControl,
FormGroup,
PageHeader } from 'react-bootstrap'
export default class LoginForm extends Component {
render(){
return (
<div className='ft-login-form'>
<PageHeader className='ft-header'><small>Login</small></PageHeader>
<form onSubmit={this.props.login}>
<FormGroup validationState={this.props.formValidationState}>
<ControlLabel className="ft-form-error-message">{this.props.errorMessage}</ControlLabel>
</FormGroup>
<FormGroup controlId="formBasicText" validationState={this.props.emailValidationState}>
<ControlLabel>Email</ControlLabel>
<FormControl
bsSize="small"
className="ft-username"
componentClass="input"
onPaste={this.props.handleEmailPaste}
onChange={this.props.handleEmailInput}
placeholder="Enter email"
style={{ width: 300}}
type="email"
value={this.props.email}
/>
<HelpBlock className="ft-email-error">{this.props.emailError}</HelpBlock>
</FormGroup>
<FormGroup validationState={this.props.passwordValidationState}>
<ControlLabel>Password</ControlLabel>
<FormControl
bsSize="small"
className="ft-password"
componentClass="input"
onPaste={this.props.handleEmailPaste}
onChange={this.props.handlePasswordInput}
placeholder="Enter password"
style={{ width: 300}}
type="password"
value={this.props.password}
/>
<HelpBlock className="ft-password-help-text">{this.props.passwordHelpText}</HelpBlock>
</FormGroup>
<Button
className='ft-login-button'
type='submit'
>Login</Button>
</form>
</div>)
}
}
UPDATE
所以我加入這一點,這樣可以解決問題:基本上這裏
handleEmailInput(e) {
if(!this.state.email) {
this.setState({email: e.target.value})
}
this.validateEmail()
}
我說,嘿,如果有人在最初粘貼它,它將擊中handleEmailPaste
這setState的電子郵件,所以如果是這樣的話(我知道handleEmailInput也將由該粘貼/更改觸發),那麼我不想再設置狀態,如果handleEmailPaste已經設置它。相反,如果用戶輸入值而不是粘貼它,那麼這個if語句將是bypassed
,因此handleEmailInput would setState in that case
。
但我的整個電子郵件輸入處理只是對我感到羞恥。如果你認爲這是一個黑客,並有更好的重構這個代碼的想法讓我知道。
更新#2
廢話,我注意到,我沒有得到複製,但現在我不能輸入Email地址框中輸入新值,它不會讓我和它只是坐在那裏與填充電子郵件,但我不能修改它。
更新#3 (咆哮:憑啥不計算器使身體後textarea的更大的高度,我幾乎看不到什麼,我這裏正在做的,當我滾動)
所以真的,我的問題不再是它複製粘貼文本的問題。我回到了原來的問題,我原來的問題是我能夠粘貼一些東西,但它使輸入無效,我無法弄清楚原因。我想我應該更新這篇文章的標題,但哦。
無論如何,我已經訴諸於只使用onChange
並擺脫onPaste。沒有更多的dups發生
所以問題:是與最初的行爲,當你第一次粘貼到電子郵件文本框的值。我看到的行爲(以下是沒有onPaste更新的代碼了)當你在第一時間的值粘貼:
- 當你在第一時間貼,它擊中我
handleEmailInput()
方法。 handleEmailInput
調用setState({email: e.target.value})
所以你會認爲現在是設置this.state.email- 但當
handleEmailInput
電話validateEmail()
後,validateEmail
,它會檢查this.state.email
和它的仍然""
出於某種原因。所以它因此結果達到第二個setState,它將其設置爲無效。
不會在第一次調用到this.setState({email: e.target.value })
設置this.state.email
到粘貼的電子郵件?我知道,當我把一個斷點上線,e.target.value
確實有我粘貼的電子郵件,但後this.setState({email: e.target.value })
完成調用,出於某種原因在validateEmail(時),它仍然得到""
爲this.state.email我不明白爲什麼。也許這是React及其生命週期的基礎?或者我還沒有意識到的其他一些基本問題......不確定。
LoginContainer (我已經完全去除onPaste邏輯)
import { connect } from 'react-redux'
import React, { Component } from 'react'
const zxcvbn = require('zxcvbn'),
_ = require('lodash')
import * as AsyncActions from '../actions/Auth/AuthAsyncActions'
import Login from '../components/Login/Login'
class LoginContainer extends Component {
constructor(props) {
super(props)
this.state = {
email: '',
password: '',
errorMessage: '',
emailValidationState: null,
formIsValid: false,
formValidationState: null,
passwordValidationState: null,
passwordIsValid: null
}
this.handleEmailInput = this.handleEmailInput.bind(this)
this.handlePasswordInput = this.handlePasswordInput.bind(this)
this.handleLoginPressed = this.handleLoginPressed.bind(this)
this.resetFields = this.resetFields.bind(this)
this.validateForm = this.validateForm.bind(this)
this.validateEmail = this.validateEmail.bind(this)
this.validatePassword = this.validatePassword.bind(this)
}
handlePasswordInput(e) {
const password = e.target.value
this.setState({ password: password})
this.validatePassword()
}
handleEmailInput(e) {
this.setState({email: e.target.value })
this.validateEmail()
}
async handleLoginPressed(e) {
e.preventDefault()
this.validateForm()
await this.props.authenticate(this.state.email, this.state.password)
if(this.props.isAuthenticated) {
this.props.history.push('/dashboard')
return
}
if(!this.props.isAuthenticated){
this.setState({
formValidationState: 'error',
errorMessage: this.state.formIsValid &&
'Your password and/or email is not associated with an active user'
})
if(this.state.email && this.state.password){this.resetFields()}
}
}
validateForm(){
this.validateEmail()
this.validatePassword()
this.setState({
formIsValid: (this.state.emailValidationState === 'success'
&& this.state.passwordValidationState === 'success')})
}
validatePassword(){
const password = zxcvbn(this.state.password)
if(password.score >=0){
this.setState({
passwordValidationState: 'error',
passwordHelpText: password.feedback.suggestions})
return
}
this.setState({
passwordValidationState: 'success',
passwordHelpText: null })
}
validateEmail(){
if(!_.isEmpty(this.state.email)) {
this.setState({
emailValidationState: 'success',
emailError: ''
})
return
}
this.setState({
emailValidationState: 'error',
emailError: 'please enter an email address'
})
}
resetFields(){
this.setState({
email: '',
emailError: '',
emailValidationState: null,
password: '',
passwordHelpText: '',
passwordValidationState: null })
}
render(){
return(
<div>
<Login
email={this.state.email}
emailError={this.state.emailError}
emailValidationState={this.state.emailValidationState}
errorMessage={this.state.errorMessage}
formValidationState={this.state.formValidationState}
handleEmailInput={this.handleEmailInput}
handlePasswordInput={this.handlePasswordInput}
login={this.handleLoginPressed}
password={this.state.password}
passwordHelpText={this.state.passwordHelpText}
passwordValidationState={this.state.passwordValidationState}
/>
</div>
)
}
}
const mapStateToProps = state => ({
isAuthenticating: state.auth.isAuthenticating,
isAuthenticated: state.auth.isAuthenticated,
token: state.auth.token
})
export const mapDispatchToProps = {
authenticate: AsyncActions.authenticate
}
export { Login }
export default connect(mapStateToProps, mapDispatchToProps)(LoginContainer)
import React, { Component } from 'react'
import {
Button,
ControlLabel,
HelpBlock,
FormControl,
FormGroup,
PageHeader } from 'react-bootstrap'
LoginForm的 (注意我們使出回只具有的onChange電子郵件)
export default class LoginForm extends Component {
render(){
return (
<div className='ft-login-form'>
<PageHeader className='ft-header'><small>Login</small></PageHeader>
<form onSubmit={this.props.login}>
<FormGroup validationState={this.props.formValidationState}>
<ControlLabel className="ft-form-error-message">{this.props.errorMessage}</ControlLabel>
</FormGroup>
<FormGroup controlId="formBasicText" validationState={this.props.emailValidationState}>
<ControlLabel>Email</ControlLabel>
<FormControl
bsSize="small"
className="ft-username"
componentClass="input"
onChange={this.props.handleEmailInput}
placeholder="Enter email"
style={{ width: 300}}
type="email"
value={this.props.email}
/>
<HelpBlock className="ft-email-error">{this.props.emailError}</HelpBlock>
</FormGroup>
<FormGroup validationState={this.props.passwordValidationState}>
<ControlLabel>Password</ControlLabel>
<FormControl
bsSize="small"
className="ft-password"
componentClass="input"
onPaste={() => this.props.handleEmailPaste}
onChange={() => this.props.handlePasswordInput}
placeholder="Enter password"
style={{ width: 300}}
type="password"
value={this.props.password}
/>
<HelpBlock className="ft-password-help-text">{this.props.passwordHelpText}</HelpBlock>
</FormGroup>
<Button
className='ft-login-button'
type='submit'
>Login</Button>
</form>
</div>)
}
}
你不能修改它,因爲你的'email'是一個[受控組件](https://facebook.github.io/react/docs/forms.html#controlled-components),它的值取決於'state',其中,因爲'如果',不更新 –
好..如果我拿出如果,然後它複製該框中的值 – PositiveGuy
是啊我卡住瞭然後如果是這樣的話,因爲我不知道如何擺脫原來的問題,那麼如果是這樣的話,而我粘貼在一封電子郵件,它dups它(不知何故它更新狀態兩次或什麼,我不知道) – PositiveGuy