javascript – Avoid unnecessary rendering in React Native with multiple TextInput

Question:

The point is, I basically have code like this (I can't send the real code right now, I'm sending this "Pseudo-Code" so ignore syntax and standardization errors):

const Componente = () => {
    const [campo1, setCamp1] = useState('');
    const [campo2, setCamp2] = useState('');
    const [campo3, setCamp3] = useState('');
    const [campo4, setCamp4] = useState('');
    const [campo5, setCamp5] = useState('');
    const [campo6, setCamp6] = useState('');
    const [campo7, setCamp7] = useState('');

    return (
        <View>
            <TextInput
                style={styles.input}
                onChangeText={setCamp1}
                value={campo1}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp2}
                value={campo2}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp3}
                value={campo3}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp4}
                value={campo4}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp5}
                value={campo5}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp6}
                value={campo6}
            />
            <TextInput
                style={styles.input}
                onChangeText={setCamp7}
                value={campo7}
            />
        </View>
    );
}

For each letter typed in each input the component re-renders itself whole, that is, it renders all inputs again. I've already tried using useRef (as I've done in ReactJS) but it wasn't effective, it gave problems in onChangeText and Value, like this (considering that camp1 was a useRef):

            <TextInput
                style={styles.input}
                OnChangeText={(value) => {camp1.current = value}}
                value={camp1.current}
            />

I also tried useMemo (separating the inputs and putting each one as a Memo). I can't/want to use libraries like unform, formik among others, both for the project and because of finding a way to solve this problem.

Is there any way to improve the performance of this component to not depend on so many states and so many renderings?

PS: Using a state only that is an object with 7 attributes wouldn't do it either, as it would frequently fire the same Setter and would render everything again).

Answer:

Yes there is, you can use the concept of uncontrolled-components .

In a controlled component, form data is manipulated by a React component. The alternative is uncontrolled components, where the form data is controlled by the DOM itself. reference

I will demonstrate through the code below:

function App() {
    const input = React.createRef();

    function handleSubmit(event) {
      event.preventDefault();
      alert('A name was submitted: ' + input.current.value);
    }
  
    return (
      <div className="App">
        <h1>Seu formulário</h1>
        <form onSubmit={handleSubmit}>
          <input type="text" ref={input} />
          <button>enviar</button>
        </form>
      </div>
    );
}

ReactDOM.render(<App />, document.querySelector("#app"))
.App {
  font-family: sans-serif;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>

<div id="app"></div>

In this solution, your component will not update every time there is a change in your form's values. And when you really need those values, you can take them by reference.

Scroll to Top