В настоящее время у меня есть компонент класса, который содержит функции, которые действуют как компоненты в моем JSX.
Пример:
class MyComponent extends React.Component {
MySubComponent = (props) => {
if (props.display) {
return <p>This text is displayed</p>
}
}
render() {
return (
<this.MySubComponent display = {true} />
)
}
}
Есть ли какие-то последствия для такого вызова компонентов? Также есть термин для этого?
Что послужило поводом для этого? Если его нет, вы пишете более сложный код, чем могли бы.
@estus Я бы хотел, чтобы функция рендеринга оставалась декларативной. Поэтому я переместил всю логику рендеринга в функции, чтобы они не находились внутри самой функции рендеринга. Я знаю, что могу легко вызвать такую функцию, как эта {this.mySubComponent ()}, но я сохраню ее, поскольку JSX облегчает чтение.
Я понимаю. На этом этапе MySubComponent не обязательно должен быть частью MyComponent, согласно принципу KISS. Компоненты можно использовать и тестировать отдельно.
@estus Я обычно согласен, но этот компонент будет использоваться только этим классом. На самом деле это просто функция класса, спорный вопрос о том, как она отображается.
Тогда это будет просто функция, которая нигде не используется, кроме текущего компонента. Это то же самое, но также более эффективное и не требует дополнительных действий, если MyComponent в будущем будет преобразован в функциональный компонент. Вот почему я упомянул KISS. Если более сложное решение не дает преимуществ, в нем нет необходимости.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это приводит к созданию новой функции MySubComponent для каждого экземпляра MyComponent, что не очень эффективно для этого.
Использование MySubComponent в качестве метода MyComponent может дать только два преимущества.
Один из них заключается в том, что MySubComponent можно заменить другой реализацией в подклассе MyComponent без изменения функции render. Это не идиоматично для React, потому что он продвигает функциональный подход вместо ООП.
Во-вторых, MySubComponent может получить доступ к экземпляру MyComponent и его свойствам. Это приводит к проблеме проектирования, потому что два компонента тесно связаны.
Ни один из этих аргументов не имеет существенного значения при разработке React. Если нет особых требований, которые требуют, чтобы MySubComponent был частью MyComponent, первый не следует определять как метод экземпляра второго. Это могло быть просто:
const MySubComponent = (props) => {
if (props.display) {
return <p>This text is displayed</p>
}
}
class MyComponent extends React.Component {
render() {
return (
<MySubComponent display = {true} />
)
}
}
А как насчет случаев, когда они должны быть тесно связаны? Например, если бы у нас не было этой функции / компонента, метод рендеринга выглядел бы примерно так: render () {return ({true && <p> Этот текст отображается </p>})}, который не является декларативным.
Похоже, что есть только 2 альтернативы: 1. Сделать функцию рендеринга императивной или 2. Создать группу внешних функциональных компонентов, чтобы гарантировать, что метод рендеринга остается декларативным. Кроме того, метод 2 работает так, как вы заявили, он кажется нелогичным, потому что компонент просто создан для того, чтобы сделать основной компонент «чище», поэтому его использование вне класса на самом деле не имеет большого смысла, с моей точки зрения.
Какие случаи вы имеете в виду? Под сильной связью я имел в виду, что MySubComponent может использовать экземпляр родительского компонента, например this.state, и это было бы ошибкой дизайна. «2» - это то, как это обычно делается в React. Я бы сказал, что парадигма ООП работает против вас. Вам не нужно помещать в класс все, что можно, только для того, чтобы обозначить, что элемент «принадлежит» ему, это антипаттерн. Классы - это не прославленные пространства имен. Уже есть модули, которые работают как пространства имен. Я сторонник ООП там, где это подходит, но на данный момент его использование совершенно не оправдано.
Вы правы, но у меня есть еще один вопрос в пользу подхода ООП. Будет ли {this.MySubComponent ()} отличаться от <this.MySubcomponent />? Если да, то почему?
Поскольку оба компонента находятся под вашим контролем, это нормально, иначе это было бы взломом. В данном конкретном случае разницы в производстве нет. Что касается разработки, они будут выглядеть иначе в инструментах разработки React, и прямой вызов может быть менее простым для тестирования. {MySubComponent({ display: true })} быстрее, но если вы сделаете это только из соображений производительности без доказательства того, что это необходимо, это можно считать предварительной оптимизацией. Я использовал это только для обходных путей. См. stackoverflow.com/questions/52047063/… для некоторых идей.
Извините, я немного запутался в вашем ответе. Итак, если я вызываю функцию напрямую как функцию. Работает ли он по-другому за кулисами, а не как компонент jsx? Например, если {MySubComponent ({display: true})} быстрее, чем <this.MySubComponent display = {true} />, почему он быстрее? И если {MySubComponent ({display: true})} работает быстрее, отличается ли это от создания компонента вне класса, как вы указали в ответе? Просто хочу знать общие различия между ними (если есть)
Прямой вызов выполняется быстрее, потому что он пропускает абстракцию элемента React, в основном вызов React.createElement и его рендеринг. React renderer в любом случае вызывает функцию изнутри. Элементы React достаточно быстры, чтобы не быть узким местом.
Это принесет пользу только в том случае, если вы используете
thisвнутри этого функционального компонента. В противном случае нет необходимости создавать его динамически. Обратите внимание: поскольку вы используете синтаксис инициализатора свойств, ваш функциональный компонент будет воссоздан для каждого экземпляра компонента на основе класса.