Функциональные компоненты внутри компонентов класса

В настоящее время у меня есть компонент класса, который содержит функции, которые действуют как компоненты в моем JSX.

Пример:

class MyComponent extends React.Component {
    MySubComponent = (props) => {
        if (props.display) {
            return <p>This text is displayed</p>
        }
    }

    render() {
        return (
            <this.MySubComponent display = {true} />
        )
    }
}

Есть ли какие-то последствия для такого вызова компонентов? Также есть термин для этого?

Это принесет пользу только в том случае, если вы используете this внутри этого функционального компонента. В противном случае нет необходимости создавать его динамически. Обратите внимание: поскольку вы используете синтаксис инициализатора свойств, ваш функциональный компонент будет воссоздан для каждого экземпляра компонента на основе класса.

trixn 06.12.2018 19:00

Что послужило поводом для этого? Если его нет, вы пишете более сложный код, чем могли бы.

Estus Flask 06.12.2018 19:00

@estus Я бы хотел, чтобы функция рендеринга оставалась декларативной. Поэтому я переместил всю логику рендеринга в функции, чтобы они не находились внутри самой функции рендеринга. Я знаю, что могу легко вызвать такую ​​функцию, как эта {this.mySubComponent ()}, но я сохраню ее, поскольку JSX облегчает чтение.

CodingMadeEasy 06.12.2018 19:04

Я понимаю. На этом этапе MySubComponent не обязательно должен быть частью MyComponent, согласно принципу KISS. Компоненты можно использовать и тестировать отдельно.

Estus Flask 06.12.2018 19:12

@estus Я обычно согласен, но этот компонент будет использоваться только этим классом. На самом деле это просто функция класса, спорный вопрос о том, как она отображается.

CodingMadeEasy 06.12.2018 19:14

Тогда это будет просто функция, которая нигде не используется, кроме текущего компонента. Это то же самое, но также более эффективное и не требует дополнительных действий, если MyComponent в будущем будет преобразован в функциональный компонент. Вот почему я упомянул KISS. Если более сложное решение не дает преимуществ, в нем нет необходимости.

Estus Flask 06.12.2018 19:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
6
20 915
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это приводит к созданию новой функции 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>})}, который не является декларативным.

CodingMadeEasy 06.12.2018 19:19

Похоже, что есть только 2 альтернативы: 1. Сделать функцию рендеринга императивной или 2. Создать группу внешних функциональных компонентов, чтобы гарантировать, что метод рендеринга остается декларативным. Кроме того, метод 2 работает так, как вы заявили, он кажется нелогичным, потому что компонент просто создан для того, чтобы сделать основной компонент «чище», поэтому его использование вне класса на самом деле не имеет большого смысла, с моей точки зрения.

CodingMadeEasy 06.12.2018 19:23

Какие случаи вы имеете в виду? Под сильной связью я имел в виду, что MySubComponent может использовать экземпляр родительского компонента, например this.state, и это было бы ошибкой дизайна. «2» - это то, как это обычно делается в React. Я бы сказал, что парадигма ООП работает против вас. Вам не нужно помещать в класс все, что можно, только для того, чтобы обозначить, что элемент «принадлежит» ему, это антипаттерн. Классы - это не прославленные пространства имен. Уже есть модули, которые работают как пространства имен. Я сторонник ООП там, где это подходит, но на данный момент его использование совершенно не оправдано.

Estus Flask 06.12.2018 19:27

Вы правы, но у меня есть еще один вопрос в пользу подхода ООП. Будет ли {this.MySubComponent ()} отличаться от <this.MySubcomponent />? Если да, то почему?

CodingMadeEasy 06.12.2018 19:38

Поскольку оба компонента находятся под вашим контролем, это нормально, иначе это было бы взломом. В данном конкретном случае разницы в производстве нет. Что касается разработки, они будут выглядеть иначе в инструментах разработки React, и прямой вызов может быть менее простым для тестирования. {MySubComponent({ display: true })} быстрее, но если вы сделаете это только из соображений производительности без доказательства того, что это необходимо, это можно считать предварительной оптимизацией. Я использовал это только для обходных путей. См. stackoverflow.com/questions/52047063/… для некоторых идей.

Estus Flask 06.12.2018 19:48

Извините, я немного запутался в вашем ответе. Итак, если я вызываю функцию напрямую как функцию. Работает ли он по-другому за кулисами, а не как компонент jsx? Например, если {MySubComponent ({display: true})} быстрее, чем <this.MySubComponent display = {true} />, почему он быстрее? И если {MySubComponent ({display: true})} работает быстрее, отличается ли это от создания компонента вне класса, как вы указали в ответе? Просто хочу знать общие различия между ними (если есть)

CodingMadeEasy 06.12.2018 19:54

Прямой вызов выполняется быстрее, потому что он пропускает абстракцию элемента React, в основном вызов React.createElement и его рендеринг. React renderer в любом случае вызывает функцию изнутри. Элементы React достаточно быстры, чтобы не быть узким местом.

Estus Flask 06.12.2018 20:01

Другие вопросы по теме