Предотвращение повторного рендеринга, вызванного заменой между простыми компонентами react

#reactjs

#reactjs

Вопрос:

 function A() {
  return <HeavyComponent someProp={true} />;
}

function B() {
  return <HeavyComponent someProp={false} />;
}

function C() {
  const [state, setState] = useState(true);
  return state ? <A /> : <B />;
}

function D() {
  const [state, setState] = useState(true);
  return state ? A() : B();
}
 

Как вы можете видеть, A и B выполняет очень простые задания.
state При C изменении с true на false , react удалит элемент, который A отрисовал, и смонтирует новый B рендеринг. Это приводит HeavyComponent к рендерингу с нуля.

Если я использую D вместо C , результат будет точно таким же. Однако. Рендеринг будет более эффективным, поскольку D будет обновляться HeavyComponent , а не удалять и отображать новый.

Проблема в том, что я хочу экспортировать оба A и B в библиотеку, и трудно ожидать, что другие программисты будут использовать A and B эффективным способом, как in D .

Я думаю, вы можете указать, что мне не нужно определять A и B . Но это всего лишь упрощенный пример. На реальной практике у меня есть более одного реквизита, а также больше компонентов. Каждый компонент представляет семантику комбинации реквизитов, передаваемых HeavyComponent по имени самого себя. Я также буду экспортировать HeavyComponent напрямую, но пользователь в первый раз запутается в своих реквизитах. Так что было бы лучше экспортировать удобные компоненты A и B .

Есть ли какой-либо способ создать A и B работать как in D , даже если программист использует их как in C ?

Комментарии:

1. Привет. Я не могу дать вам точный ответ, но вы можете найти его здесь reactjs.org/docs/reconciliation.html

2. Ваша задача как автора библиотеки — экспортировать основные компоненты, которые должны использоваться потребителем, и программист должен знать, как правильно обрабатывать свои собственные сценарии — вы не можете защитить пользователя от незнания, как правильно использовать компоненты react, вот что я говорю. Что вы могли бы сделать, это, возможно, просто добавить заметки об использовании определенных компонентов, которые действительно тяжелы для повторного рендеринга.

Ответ №1:

Вероятно, вы имели в виду повторное монтирование, а не повторное рендеринг. Ответ в том, что вы не можете, не при использовании C.

И с D, A и B больше не могут обрабатывать состояние и эффекты; что делает их скорее служебной функцией и меньшим компонентом.

Что вы могли бы сделать, это экспортировать пользовательский хук, чтобы вернуть реквизит по умолчанию для распространения в <HeavyComponent>

 function E() {
    const [state, setState] = useState(false)
    const aProps = useA()
    const bProps = useB()
    const props = state ? aProps : bProps

    return <HeavyComponent {...props} />
}
 

Конечно, вам не нужно использовать перехваты (вы можете просто использовать обычную функцию), но это позволяет вам включать состояние и эффекты, как если бы это был полноценный <A> компонент, с преимуществом отсутствия размонтирования и перемонтирования.

Ответ №2:

В качестве другого возможного обходного пути вы можете создать компонент, который инкапсулирует различные комбинации реквизитов, например:

 function DecoratedHeavyComponent({ variant, props }) {

  const variantProps = {
    A: { someProp: true },
    B: { someProp: false },
    // etc...
  }

  return <HeavyComponent {...props} {...variantProps[variant]} />;
}
 

Может быть дополнительно использован следующим образом:

 function C() {
  const [state, setState] = useState(true);
  return <DecoratedHeavyComponent variant={ state ? 'A' : 'B' } />;
}