这是一个示例,其中输入字段作为一个组件插入,输入字段中的每个更改都失去了焦点。看来,当您更改整个组件时会重新渲染,而那些失去焦点,实现这种动态形式的最佳实践是什么,以及如何在此处防止失去焦点?
PS:这是一个较复杂的表单的一部分的小示例,该表单的每个后续部分取决于上一个表单的选择。
import ReactDOM from 'react-dom'
import React, { useReducer } from 'react'
import Select from 'react-select'
const SELECT_UPDATED = 'INPUT_UPDATED'
const TEXT_UPDATED = 'TEXT_UPDATED'
const TEXT_UPDATED2 = 'TEXT_UPDATED2'
const INITIAL_STATE = {
selectedType: '',
inputText: '',
inputText2: ''
}
let reducer = (state, action) => {
switch (action.type) {
case SELECT_UPDATED:
return { ...state, selectedType: action.selectedType }
case TEXT_UPDATED:
return { ...state, inputText: action.inputText }
case TEXT_UPDATED2:
return { ...state, inputText2: action.inputText2 }
default:
return state
}
}
function App() {
const [state, dispatch] = useReducer(reducer, INITIAL_STATE)
console.log('state: ', state)
return (
<div>
<Select
options={[{ value: 'edit_text', label: 'Edit text' }, { value: 'hide_input', label: 'Hide input' }]}
onChange={e => dispatch({ type: SELECT_UPDATED, selectedType: e.value })}
/>
<p/>
<SecondStep />
</div>
)
function SecondStep() {
if (state.selectedType === 'edit_text') {
return <div>
<input type="text" autoFocus value={state.inputText} onChange={e => dispatch({ type: TEXT_UPDATED, inputText: e.target.value })} />
<input type="text" autoFocus value={state.inputText2} onChange={e => dispatch({ type: TEXT_UPDATED2, inputText2: e.target.value })} />
</div>
} else if (state.selectedType === 'hide_input') {
return <div>Hidden input</div>
} else {
return <div>NA</div>
}
}
}
ReactDOM.render(<App />, document.getElementById('root'))
答案 0 :(得分:1)
您可以像这样将autoFocus属性用于输入
<input type="text" autoFocus value={state.inputText} onChange={e => dispatch({ type: TEXT_UPDATED, inputText: e.target.value })} />
更新
我刚刚更改了您的代码,下面我在这里使用了3个输入框
import ReactDOM from 'react-dom'
import React, { useReducer } from 'react'
import Select from 'react-select'
const SELECT_UPDATED = 'INPUT_UPDATED'
const TEXT_UPDATED = 'TEXT_UPDATED'
const TEXT_UPDATED1 = 'TEXT_UPDATED1'
const TEXT_UPDATED2 = 'TEXT_UPDATED2'
const INITIAL_STATE = {
selectedType: '',
inputText: '',
inputText1: '',
inputText2: '',
autoFocus1:true,
autoFocus2:false,
autoFocus3:false,
}
let reducer = (state, action) => {
console.log(action.type)
switch (action.type) {
case SELECT_UPDATED:
return { ...state, selectedType: action.selectedType }
case TEXT_UPDATED:
return { ...state, inputText: action.inputText, autoFocus1:true, autoFocus2:false, autoFocus3:false }
case TEXT_UPDATED1:
return { ...state, inputText1: action.inputText1 , autoFocus1:false, autoFocus2:true, autoFocus3:false }
case TEXT_UPDATED2:
return { ...state, inputText2: action.inputText2 , autoFocus1:false, autoFocus2:false, autoFocus3:true }
default:
return state
}
}
function App() {
const [state, dispatch] = useReducer(reducer, INITIAL_STATE)
console.log('state: ', state)
return (
<div>
<Select
options={[{ value: 'edit_text', label: 'Edit text' }, { value: 'hide_input', label: 'Hide input' }]}
onChange={e => dispatch({ type: SELECT_UPDATED, selectedType: e.value })}
/>
<SecondStep />
</div>
)
function SecondStep() {
if (state.selectedType === 'edit_text') {
return (
<div>
<input type="text" autoFocus={state.autoFocus1} value={state.inputText} onChange={e => dispatch({ type: TEXT_UPDATED, inputText: e.target.value })} />
<input type="text" autoFocus={state.autoFocus2} value={state.inputText1} onChange={e => dispatch({ type: TEXT_UPDATED1, inputText1: e.target.value })} />
<input type="text" autoFocus={state.autoFocus3} value={state.inputText2} onChange={e => dispatch({ type: TEXT_UPDATED2, inputText2: e.target.value })} />
</div>
)
} else if (state.selectedType === 'hide_input') {
return <div>Hidden input</div>
} else {
return <div>NA</div>
}
}
}
ReactDOM.render(<App />, document.getElementById('root'))
答案 1 :(得分:0)
如果问题与重新渲染有关,则可以为组件分配键值,这样,在状态更新后被视为保留的组件将不会被卸载/重新安装。