javascript - Ako môžem zabrániť tomu, aby sa zložená komponenta znovu renderovala?
Používam react context a momentálne obsahuje iba 3 položky: contacts, editingContact a editContact:
interface ContactsContextProps {
contacts: Contact[];
editingContact: Contact;
editContact: (contact: Contact) => () => void // being lazy and this is from an onClick
}
const ContactsContext = React.createContext<Partial<ContactsContextProps>>({
editContact: (contact: Contact) => () => {}
})
const ContactsProvider: React.FunctionComponent = props => {
const [contacts, setContacts] = useState<Contact[]>();
const [editingContact, setEditingContact] = useState<Contact>();
React.useEffect(() => {
// fetch contacts, and setContacts(contacts)
}, [])
const editContact = React.useCallback((contact: Contact) => {
return function() {
setEditingContact(contact);
}
})
return (
<ContactsContext.Provider
value={{
editingContact,
editContact,
contacts
}}
>
{props.children}
</ContactsContext.Provider>
)
}
Tu je to, ako sa to používa:
const ContactsList: React.FunctionComponent<{
contacts: Contact[];
}> = React.memo(props => {
return (
<>
{props.contacts.map(contact => (
<Card key={contact.id} contact={contact} />
))}
</>
);
});
const Wrapper: React.FunctionComponent = () => {
const contactsCtx = React.useContext(ContactsContext);
return (
<>
<Box className={styles.main}>
<Header />
{contactsCtx.contacts && <ContactsList contacts={contactsCtx.contacts} />}
</Box>
{contactsCtx.editingContact && <EditContactModal />}
</>
);
};
Komponent <Card /> momentálne má iba tlačidlo na úpravu, ktoré volá contactsContext.editContact(). Avšak, zakaždým, keď sa toto volá, všetky Karty sa znovu vykreslia. Do každej Karty som vložil console.log('card') a zaznamenáva sa card 10-krát (momentálne mám 10 kontaktov).
Čo robím zle?
Odpoveď č. 1
V diskusii na GitHub issue o Reacte sa objavila debata, v podstate existujú 3 možné riešenia tohto problému:
- Možnosť 1 (uprednostňovaná): Rozdeľte kontexty, ktoré sa nemenia spolu
- Možnosť 2: Rozdeľte svoju komponentu na dve časti, medzi ne vložte
memo - Možnosť 3: Jeden komponent s
useMemovo vnútri
Mali by ste si skontrolovať odkaz pre príklady o tom.