Правильный способ назначения реквизита для дочернего компонента

Интересно, какой способ назначения реквизитов, которые будут переданы дочернему компоненту, является правильным (как с точки зрения корректности React (синтаксис, общие практики), так и эффективности), и если есть гораздо лучший способ добиться этого, пожалуйста, дайте мне знать.

Итак, в настоящее время в моем проекте у меня есть родительский компонент, который получает некоторые данные и передает их дочернему элементу (на самом деле я собираюсь инкапсулировать его еще дальше, и дочерний элемент получает данные, но мне все еще любопытно, какое правильное решение ).

Мой код выглядит примерно так:

class Dashboard extends Component {

    constructor(props) {
        super(props)

        this.state = {
            a: 'foo',
            b: 'bar',
            stats: {
                c: 'c',
                d: 'd'
            }
        }
    }

    someFunction = () => {

    }

  render() {
    let childData = this.state.stats
    childData.function = this.someFunction

    return (
      <div>
        <ChildComponent {...childData}/>
      </div>
    )
  }
}

Как видите, я назначаю все данные для дочернего компонента внутри render(), и на самом деле для этого нет особой причины. Я видел это в одном видео на Lynda, когда смотрел материалы React, и мне это понравилось. Я считаю, что мог бы просто сделать это:

constructor(props) {
    super(props)

    this.state = {
        a: 'foo',
        b: 'bar',
        stats: {
            c: 'c',
            d: 'd'
        }
    }

    let childData = this.state.stats
    childData.function = this.someFunction 
}

Я хотел бы знать, какой из них, если таковой имеется, является более «реагирующим» способом сделать это, или есть ли лучший способ? Правильно ли я думаю, что может быть проблема с производительностью, когда эти данные назначаются каждый раз, когда родительский компонент отображается? Если да, будет ли это сведено к минимуму, если я перенесу логику в конструктор, чтобы присваивание происходило только один раз?

Спасибо за помощь!

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

azium 25.03.2019 12:30

@azium это будет веб-сайт, отображающий изменения в процессе физической сборки в режиме реального времени. Изменения отправляются из серверной части, работающей на NodeJS, через веб-сокеты. И интерфейс, и сервер работают на ПК под управлением Windows. Конкретная страница (из вопроса) будет отображаться на большом экране телевизора через raspberryPi, поэтому я пытаюсь сделать ее максимально легкой/правильной. Мне сказали на wok, что raspberryPi может с трудом отображать страницы в React из-за рендеринга, хотя не уверен, сколько в этом правды.

Irek 25.03.2019 13:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Так что я бы сказал, что ни один из этих вариантов не является «путем React». Взяв ваш точный компонент, я бы сказал, что наиболее распространено следующее:

class Dashboard extends Component {
  constructor(props) {
    super(props)

    this.state = {
      a: 'foo',
      b: 'bar',
      stats: {
        c: 'c',
        d: 'd',
      },
    }
  }

  someFunction = () => {}

  render() {
    return (
      <div>
        <ChildComponent
          stats = {this.state.stats}
          handleSomeEvent = {this.someFunction}
        />
      </div>
    )
  }
}

Однако это только самый распространенный способ до версии 16.8. Вместо этого наиболее распространенным способом будет следующее:

function Dashboard() {
  const [state, setState] = useState({
    a: 'foo',
    b: 'bar',
    stats: {
      c: 'c',
      d: 'd',
    },
  })

  const someFunction = () => {}

  return (
    <div>
      <ChildComponent 
        stats = {state.stats} 
        handleSomeEvent = {someFunction} 
      />
    </div>
  )
}

Я использовал этот метод несколько раз на протяжении всего проекта, и я обнаружил, что когда у вас есть несколько функций/переменных, которые вы хотите передать дочерним элементам, это может привести к немного длинному коду (стеку). Затем я подумал, что использование оператора распространения и присваивания (как я сделал выше) сделает код «красивее». Хотя, если это наиболее подходящий способ сделать это, мне придется измениться. Спасибо!

Irek 25.03.2019 13:09

Да, это может быть правильный путь.

Дорогостоящая часть манипулирует DOM. Снижение производительности смягчается React, и вы можете значительно помочь, используя PureComponent или функцию memo для объявления вашего дочернего компонента.

Чистые компоненты и запомненные функциональные компоненты выполняют неглубокое сравнение и перерисовываются только в случае сбоя поверхностного сравнения. Неглубокое сравнение выполняется в shouldComponentUpdate для PureComponent. Вы также можете реализовать свою собственную функцию shouldComponentUpdate в «нормальном» Component. Если это вернет false, ваш дочерний компонент не будет повторно отображаться.

Итак, повторюсь. Создает ли назначение свойств дочерним компонентам накладные расходы? Да, однако это не так много по сравнению с другими накладными расходами, с которыми столкнется ваше приложение.

Что касается конкретного ответа, отличного от React. Код должен быть читабельным и понятным. Создавать промежуточный объект только для того, чтобы его деструктурировать, особого смысла нет.

Итак, это:

let childData = this.state.stats
childData.function = this.someFunction

Не очень нужен. Скорее назначьте непосредственно вашему компоненту

Спасибо за ответ с подробным объяснением. Говоря «назначить напрямую», вы имеете в виду использование метода, показанного @azium ниже?

Irek 25.03.2019 13:06

да, как у @azium.

Leon 26.03.2019 00:49

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