Reputation: 8851
I am using react context, and all it contains at the moment are 3 items: contacts
and editingContact
, and 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>
)
}
Here's how it is being used:
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 />}
</>
);
};
The <Card />
only has an edit button right now, which calls contactsContext.editContact()
. However, each time this is called, all the Cards re-render. I placed a console.log('card')
in each Card, and it logs card
10 times (I have 10 contacts right now).
What am I doing wrong?
Upvotes: 3
Views: 387
Reputation: 385
There has been a discussion in a React Github issue, basically there is 3 possible solutions for this:
memo
in betweenuseMemo
insideYou should check the link for examples about it.
Upvotes: 1