#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' } />;
}