TextField Renderizza non necessari
Ho notato un problema in cui ogni componente all'interno dello stesso genitore ( App nell'esempio sotto) verrà rieseguito quando cambiano stati / oggetti di scena non correlati, rendendo la pagina / i moduli più lenti.
Ho seguito molti consigli come la memorizzazione di gestori di eventi e oggetti di scena, ma i componenti non correlati vengono ancora riprodotti. Sono perplesso. Cosa non capisco di React?
[ CodeSandbox ] Nel debugger di React, abilita: Evidenzia gli aggiornamenti durante il rendering dei componenti
import React, { useMemo, useState } from "react";
import { TextField } from "@material-ui/core";
function MyTextInput(props) {
return (
<TextField
variant={"outlined"}
onChange={props.onChange}
value={props.value}
/>
);
}
export default function App() {
const [exampleTextValue1, setExampleTextValue1] = useState("");
const [exampleTextValue2, setExampleTextValue2] = useState("");
const handleChange1 = useMemo(
() => (event) => setExampleTextValue1(event.target.value),
[]
);
const handleChange2 = useMemo(
() => (event) => setExampleTextValue2(event.target.value),
[]
);
return (
<>
<div>
Change me:
<MyTextInput value={exampleTextValue1} onChange={handleChange1} />
</div>
<div>
Unrelated inputs. Should not re-render:
<MyTextInput value={exampleTextValue2} onChange={handleChange2} />
<MyTextInput value={exampleTextValue2} onChange={handleChange2} />
{/* to feel the impact, copy the above line like 98 more times */}
</div>
</>
);
}
Risposte
Gli strumenti del debugger sono buggati per quanto riguarda i componenti memoizzati. Quando si memorizzano i componenti, in realtà non vengono nuovamente renderizzati, ma gli strumenti di debug li evidenziano comunque (vederehttps://github.com/facebook/react/issues/19778).
Per testare effettivamente il re-rendering, modificare il valore di stato predefinito per il secondo input (che viene reso molte volte) in qualcosa come "test", quindi inserire un componente console.logall'interno di un memo MyTextInputper vedere quali vengono effettivamente ri-renderizzati:
const MyTextInput = React.memo((props) => {
console.log(props.value);
return (
<TextField
variant={"outlined"}
onChange={props.onChange}
value={props.value}
disabled={props.disabled}
/>
);
});
Puoi vedere che stampa il valore "test" una volta per tutti i secondi input quando vengono renderizzati per la prima volta, quindi mentre digiti il primo, non registra tutti i secondi input console.loggrazie alla memoizzazione.