javascript - 如何防止复合组件重新渲染?

标签 javascript reactjs typescript

我正在使用 React 上下文,目前它只包含 3 个项目:contactseditingContact , 和 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/

相关文章:

javascript - 使用自定义 Javascript 绑定(bind)在 Python 中嵌入 Gecko

javascript - 配额超出错误 : The quota has been exceeded - progressive web app offline mode

angular - 浏览器语言检测

reactjs - 为 `match` 连接 React Router 和 TypeScript

angular - 在 typescript 中定义抽象类的类型

javascript - Angular 2 路由组件无法正确渲染

javascript - AngularJS 混淆

javascript - 如果在循环中找到多个键,如何获取它的值?

javascript - ReactJS 渲染从 Laravel Controller 作为 json 字符串传递的数据

node.js - 使用Ubuntu在远程服务器上部署nodejs应用程序