React - 专注于 DOM 中的 "input" 元素(呈现为列表的元素)在按键后消失
React - Focus on an "input" element (rendered as an element of a list) in the DOM vanishes after keypress
我希望 "input" 元素在按键后仍保持焦点
代码:
import React, { Component } from 'react'
class App extends Component {
render() {
return (
<NewContactBox/>
)
}
}
class NewContactBox extends Component {
constructor(props) {
super(props)
this.state = {
name: '',
email: '',
phone: '',
}
this.fieldRefs = {
name: React.createRef(),
email: React.createRef(),
phone: React.createRef(),
}
}
hc = (ev, type, ref) => {
this.setState({
[type]: ev.target.value
})
// console.log(ref)
ref.focus()
}
render() {
const ContactInput = ({fields}) => (
fields.map((f) => (
<input
key={f.id}
className={`p-1 my-3 w-100 mr-3 ${f.id}`}
size="16px"
placeholder={f.placeholder}
value={this.state[f.id]}
ref={this.fieldRefs[f.id]}
onChange={(e) => this.hc(e, f.id, this.fieldRefs[f.id].current)}
/>
))
)
return (
<ContactInput
fields={[
{ placeholder: "Name", id: 'name' },
{ placeholder: "Phone number", id: 'phone' },
{ placeholder: "Email", id: 'email' },
]}
/>
)
}
}
export default App
我试过了
Change01
- 以另一种方式在 Input 标签内声明 refs
Change02
- 不显式地将 ref 传递给 onChange,然后直接从 this.fieldrefs
访问 ref
constructor(props) {
this.fieldRefs = {} // Change01
}
hc = (ev, type) => { //Change02
this.setState({
[type]: ev.target.value
})
// console.log(this.fieldRefs[type].current)
this.fieldRefs[type].current.focus()
}
...
<input
...
ref={(el) => this.fieldRefs[f.id] = el} //Change01
onChange={(e) => this.hc(e, f.id)} //Change02
/>
但这并没有帮助,每次按键后,body 元素都变成了活动元素。
也许您需要将 ContactInput
声明移到 render()
之外,否则每次重新呈现时都会重新创建一个新组件。例如,
render() {
return (
<this.ContactInput
fields={[
{ placeholder: "Name", id: 'name' },
{ placeholder: "Phone number", id: 'phone' },
{ placeholder: "Email", id: 'email' },
]}
/>
)
}
ContactInput = ({fields}) => (
// If react complains about returning multiple component, add this React.Fragment short syntax
<React.Fragment>
{fields.map((f) => (
<input
key={f.id}
className={`p-1 my-3 w-100 mr-3 ${f.id}`}
size="16px"
placeholder={f.placeholder}
value={this.state[f.id]}
ref={this.fieldRefs[f.id]}
onChange={(e) => this.hc(e, f.id, this.fieldRefs[f.id].current)}
/>
))}
<React.Fragment/>
)
我希望 "input" 元素在按键后仍保持焦点
代码:
import React, { Component } from 'react'
class App extends Component {
render() {
return (
<NewContactBox/>
)
}
}
class NewContactBox extends Component {
constructor(props) {
super(props)
this.state = {
name: '',
email: '',
phone: '',
}
this.fieldRefs = {
name: React.createRef(),
email: React.createRef(),
phone: React.createRef(),
}
}
hc = (ev, type, ref) => {
this.setState({
[type]: ev.target.value
})
// console.log(ref)
ref.focus()
}
render() {
const ContactInput = ({fields}) => (
fields.map((f) => (
<input
key={f.id}
className={`p-1 my-3 w-100 mr-3 ${f.id}`}
size="16px"
placeholder={f.placeholder}
value={this.state[f.id]}
ref={this.fieldRefs[f.id]}
onChange={(e) => this.hc(e, f.id, this.fieldRefs[f.id].current)}
/>
))
)
return (
<ContactInput
fields={[
{ placeholder: "Name", id: 'name' },
{ placeholder: "Phone number", id: 'phone' },
{ placeholder: "Email", id: 'email' },
]}
/>
)
}
}
export default App
我试过了
Change01
- 以另一种方式在 Input 标签内声明 refsChange02
- 不显式地将 ref 传递给 onChange,然后直接从this.fieldrefs
访问 ref
constructor(props) {
this.fieldRefs = {} // Change01
}
hc = (ev, type) => { //Change02
this.setState({
[type]: ev.target.value
})
// console.log(this.fieldRefs[type].current)
this.fieldRefs[type].current.focus()
}
...
<input
...
ref={(el) => this.fieldRefs[f.id] = el} //Change01
onChange={(e) => this.hc(e, f.id)} //Change02
/>
但这并没有帮助,每次按键后,body 元素都变成了活动元素。
也许您需要将 ContactInput
声明移到 render()
之外,否则每次重新呈现时都会重新创建一个新组件。例如,
render() {
return (
<this.ContactInput
fields={[
{ placeholder: "Name", id: 'name' },
{ placeholder: "Phone number", id: 'phone' },
{ placeholder: "Email", id: 'email' },
]}
/>
)
}
ContactInput = ({fields}) => (
// If react complains about returning multiple component, add this React.Fragment short syntax
<React.Fragment>
{fields.map((f) => (
<input
key={f.id}
className={`p-1 my-3 w-100 mr-3 ${f.id}`}
size="16px"
placeholder={f.placeholder}
value={this.state[f.id]}
ref={this.fieldRefs[f.id]}
onChange={(e) => this.hc(e, f.id, this.fieldRefs[f.id].current)}
/>
))}
<React.Fragment/>
)