大量输入 React-native 后 TextInput 变慢
TextInput becomes slow after lots of typing React-native
我对 React Native 还很陌生,目前我正在使用 expo 构建一个小应用程序。当前,当我们在文本字段中连续键入时,我正面临一个问题,即文本输入变慢,即在我的项目中,如果用户在第一个字段中自动输入 3 个数字,它将移至下一个字段。但是如果我们做连续的数据提交输入从第一个到第二个的切换有点太慢了。我找不到任何解决方案。
这是工作零食Snack
这是我试过的代码
*注意:Numberinput 是自定义输入组件
const ref = React.useRef(View.prototype);
const firstref = React.useRef(View.prototype);
<View style={styles.textinputViewleft}>
<NumberInput
style={styles.textinput}
ref={firstref}
label="Digit"
returnKeyType="next"
value={digit.value}
onChangeText={(text) => { setDigit({ value: text, error: '' }); if (text.length === 3) { ref.current.focus(); } }}
error={!!digit.error}
errorText={digit.error}
keyboardType="numeric"
maxLength={3}
minLength={3}/>
</View>
<View style={styles.textinputView}>
<NumberInput
style={styles.textinput}
ref={ref}
label="Count"
value={count.value}
onChangeText={(text) => setCount({ value: text, error: '' })}
error={!!count.error}
errorText={count.error}
keyboardType="numeric"
maxLength={3}/>
</View>
在您的示例中,每次输入的不必要渲染次数应超过 4 次,我确实为您提供了使用 ref 的更好方法,请检查:
let renderApp = 0;
const App = () => {
const [inputState,setInputState] = React.useState([])
return (
<div>
<div>Render App: {++renderApp}</div>
<NumberInput setInputState={setInputState}/>
<table>
{inputState.map((data,i)=>(
<tr>
<th>Digit:{data.digit.value}</th>
<th>Error:{data.digit.error}</th>
<th>Count:{data.count.value}</th>
<th>Error:{data.count.error}</th>
</tr>
))}
</table>
</div>
)
}
let renderInput = 0;
const NumberInput = ({setInputState}) => {
const refs = {
count: React.useRef(null),
digit: React.useRef(null)
}
const inputHandler = (e) => {
const name = e.target.name;
const value = e.target.value;
if(value.length === 3){
if(name === "count") {
setInputState((prev)=>([...prev,{
digit:{ value: refs.count.current.value, error: '' },
count:{ value: refs.digit.current.value, error: '' }}
]))
}
refs[name].current.focus()
refs[name].current.select();
}
}
return (
<div>
<div>Render Inputs: {++renderInput}</div>
<input
ref={refs.count}
label="Digit"
name="digit"
onChange={inputHandler}
type="number"
maxLength={3}
/>
<input
ref={refs.digit}
label="Count"
name="count"
onChange={inputHandler}
type="number"
maxLength={3}
/>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
我对 React Native 还很陌生,目前我正在使用 expo 构建一个小应用程序。当前,当我们在文本字段中连续键入时,我正面临一个问题,即文本输入变慢,即在我的项目中,如果用户在第一个字段中自动输入 3 个数字,它将移至下一个字段。但是如果我们做连续的数据提交输入从第一个到第二个的切换有点太慢了。我找不到任何解决方案。
这是工作零食Snack
这是我试过的代码
*注意:Numberinput 是自定义输入组件
const ref = React.useRef(View.prototype);
const firstref = React.useRef(View.prototype);
<View style={styles.textinputViewleft}>
<NumberInput
style={styles.textinput}
ref={firstref}
label="Digit"
returnKeyType="next"
value={digit.value}
onChangeText={(text) => { setDigit({ value: text, error: '' }); if (text.length === 3) { ref.current.focus(); } }}
error={!!digit.error}
errorText={digit.error}
keyboardType="numeric"
maxLength={3}
minLength={3}/>
</View>
<View style={styles.textinputView}>
<NumberInput
style={styles.textinput}
ref={ref}
label="Count"
value={count.value}
onChangeText={(text) => setCount({ value: text, error: '' })}
error={!!count.error}
errorText={count.error}
keyboardType="numeric"
maxLength={3}/>
</View>
在您的示例中,每次输入的不必要渲染次数应超过 4 次,我确实为您提供了使用 ref 的更好方法,请检查:
let renderApp = 0;
const App = () => {
const [inputState,setInputState] = React.useState([])
return (
<div>
<div>Render App: {++renderApp}</div>
<NumberInput setInputState={setInputState}/>
<table>
{inputState.map((data,i)=>(
<tr>
<th>Digit:{data.digit.value}</th>
<th>Error:{data.digit.error}</th>
<th>Count:{data.count.value}</th>
<th>Error:{data.count.error}</th>
</tr>
))}
</table>
</div>
)
}
let renderInput = 0;
const NumberInput = ({setInputState}) => {
const refs = {
count: React.useRef(null),
digit: React.useRef(null)
}
const inputHandler = (e) => {
const name = e.target.name;
const value = e.target.value;
if(value.length === 3){
if(name === "count") {
setInputState((prev)=>([...prev,{
digit:{ value: refs.count.current.value, error: '' },
count:{ value: refs.digit.current.value, error: '' }}
]))
}
refs[name].current.focus()
refs[name].current.select();
}
}
return (
<div>
<div>Render Inputs: {++renderInput}</div>
<input
ref={refs.count}
label="Digit"
name="digit"
onChange={inputHandler}
type="number"
maxLength={3}
/>
<input
ref={refs.digit}
label="Count"
name="count"
onChange={inputHandler}
type="number"
maxLength={3}
/>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>