大量输入 React-native 后,TextInput 变得很慢

IT技术 reactjs react-native react-native-android
2021-04-30 13:54:35

我对 React Native 非常陌生,目前我正在使用 expo 构建一个小应用程序。目前,当我们在文本字段中连续输入文本输入时,我遇到了一个问题,即在我的项目中,如果用户在第一个字段中自动输入 3 个数字,它将移至下一个字段。但是如果我们做连续数据提交,输入从第一个到第二个的切换有点太慢了。我找不到任何解决方案。

这是工作小吃零食

这是我尝试过的代码

*注意: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>
1个回答

在您的示例中,每个输入的非必要渲染次数应超过 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>