我在使用输入时遇到问题...我有两个输入:一个有自动对焦,另一个没有。但是,当我输入第二个输入时,它会失去焦点,焦点会返回到第一个输入。
我已经读过,当我输入内容时,React会重新呈现我的组件。我尝试了一个关键的道具等,但没有任何效果。
在我的表单(名为Signup的组件)中,我有以下内容:
import React from 'react'
import Input from '../../components/Input'
import styles from './styles.scss'
class Signup extends React.Component {
constructor (props) {
super(props)
this.state = {
name: '',
email: '',
}
}
onSignup (e, userData) {
e.preventDefault()
this.props.onSignup(userData)
}
render () {
return (
<main className={styles.wrapper}>
<div className={styles.formSide}>
<h1>SIGNUP</h1>
<Input
id="name"
label="Name"
onChange={e => this.setState({ name: e.target.value })}
autofocus={true}
/>
<Input
id="email"
label="E-mail"
onChange={e => this.setState({ email: e.target.value })}
/>
</div>
</main>
)
}
}
Signup.propTypes = {
onSignup: React.PropTypes.func.isRequired
}
export default Signup
我的组件输入有以下代码:
import React, { PropTypes } from 'react'
import MaskedInput from 'react-maskedinput'
import styles from './styles.scss'
function Input (props) {
let iconComp
if (props.icon) {
iconComp = (<img src={props.icon} alt="Icon" />)
}
let input = ''
if (props.type === 'date') {
input = (
<MaskedInput
ref={inp => inp && props.autofocus && inp.focus()}
onChange={props.onChange}
mask="11/11/1111"
placeholder={props.placeholder}
className={styles.input}
/>
)
} else {
input = (
<input
ref={inp => inp && props.autofocus && inp.focus()}
onChange={props.onChange}
id={props.id}
placeholder={props.placeholder}
type={props.type}
className={styles.input}
/>
)
}
return (
<div className={styles.wrapper}>
<label htmlFor={props.id} className={styles.label}>{props.label}</label>
<br />
{input}
{props.error &&
<span className={styles.error}>
{props.errorMessage}
</span>
}
{iconComp}
</div>
)
}
Input.propTypes = {
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
icon: PropTypes.string,
placeholder: PropTypes.string,
type: PropTypes.string,
autofocus: PropTypes.bool,
onChange: PropTypes.func.isRequired,
error: PropTypes.bool,
errorMessage: PropTypes.string
}
Input.defaultProps = {
icon: '',
placeholder: '',
type: 'text',
autofocus: false,
error: false,
errorMessage: ''
}
export default Input
我该如何解决这个问题?
答案 0 :(得分:1)
所以一个简单的解决方案是增强你的SignUp组件以获得另一个名为nameAutoFocus的属性并将其初始化为true。使用此属性设置自动对焦布尔值。然后将方法componentDidMount和set nameAutoFocus内部添加到false。
class Signup extends React.Component {
constructor (props) {
super(props)
this.state = {
name: '',
email: '',
}
this.nameAutoFocus = true; //new
}
onSignup (e, userData) {
e.preventDefault()
this.props.onSignup(userData)
}
//new
componentDidMount() {
this.nameAutoFocus = false;
}
render () {
return (
<main>
<div>
<h1>SIGNUP</h1>
<Input
id="name"
label="Name"
onChange={e => this.setState({ name: e.target.value })}
autofocus={this.nameAutoFocus}
/>
<Input
id="email"
label="E-mail"
onChange={e => this.setState({ email: e.target.value })}
/>
</div>
</main>
)
}
}
这是有效的,因为nameAutoFocus的初始值传递给输入,使其成为焦点,然后componentDidMount将运行将其设置为false,因此下次状态更改时不会将autofocus属性设置为true。这基本上是在最初渲染时只给它一次焦点。
codepen:http://codepen.io/floor_/pen/PmNRKV?editors=0011 不要忘记点击运行。
答案 1 :(得分:0)
问题是每次渲染输入时,都会为const path = require('path');
const webpack = require('webpack');
const spawn = require('child_process').spawn;
const HtmlWebpackPlugin = require('html-webpack-plugin');
const compiler = webpack({
// add your webpack configuration here
entry: './app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'es2015', 'stage-2']
}
}
}
]
},
/*plugins: [
new HtmlWebpackPlugin({
title: 'Project Demo',
hash: true,
template: './views/index.ejs' // Load a custom template (ejs by default see the FAQ for details)
})
],*/
node: {
__dirname: false
},
target: 'node'
});
const watchConfig = {
// compiler watch configuration
// see https://webpack.js.org/configuration/watch/
aggregateTimeout: 300,
poll: 1000
};
let serverControl;
compiler.watch(watchConfig, (err, stats) => {
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
return;
}
const info = stats.toJson();
if (stats.hasErrors()) {
info.errors.forEach(message => console.log(message));
return;
}
if (stats.hasWarnings()) {
info.warnings.forEach(message => console.log(message));
}
if (serverControl) {
serverControl.kill();
}
// change filename to the relative path to the bundle created by webpack, if necessary(choose what to run)
serverControl = spawn('node', [path.resolve(__dirname, 'dist/bundle.js')]);
serverControl.stdout.on('data', data => console.log(data.toString()));
serverControl.stderr.on('data', data => console.error(data.toString()));
});
创建新的线箭头函数并调用它。所以每次都执行ref
。避免这种情况的一种方法是使用类组件并将inp.focus()
回调方法定义为类函数。
ref
更新了codepen:http://codepen.io/anon/pen/jmqxWy
(我之前的代码有一些问题,因为我无法测试它。但现在我已经更新了代码并且它有效)