我正在使用 React 上下文,目前它只包含 3 个项目:contacts
和 editingContact
, 和 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>
)
}
这是它的使用方式:
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 />}
</>
);
};
<Card />
现在只有一个编辑按钮,调用contactsContext.editContact()
.但是,每次调用此方法时,所有卡片都会重新呈现。我放了一个 console.log('card')
在每张卡片中,它记录 card
10 次(我现在有 10 个联系人)。
我做错了什么?
最佳答案
React Github issue 中有讨论,基本上有 3 种可能的解决方案:
- 选项 1(首选):拆分不一起更改的上下文
- 选项 2:将您的组件一分为二,将
memo
放在中间 - 选项 3:一个包含
useMemo
的组件
您应该查看链接以获取相关示例。
关于javascript - 如何防止复合组件重新渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58034434/