Функции внутри и снаружи render ()

Я только начал изучать React и JavaScript в целом. После прочтения документации и руководств я просмотрел примеры проектов и попытался разобраться в том, чего я еще не получил.

А потом я увидел, что есть функции, которые определены внутри функций render(), а некоторые - вне функции render().

Например. для вне render():

handleClick(e) {
    e.preventDefault();
    e.target.parentElement.classList.toggle('open');
  }

и внутри render () ...

const divider = (divider, key) => {
      const classes = classNames( 'divider', divider.class);
      return (<li key = {key} className = { classes }></li>);
    };

Почему они выглядят так по-разному и почему вы хотели бы иметь некоторые функции внутри, а некоторые за пределами render()?

Обновлено:

Другой пример для функции вне render():

hideMobile() {
    if (document.body.classList.contains('sidebar-mobile-show')) {
      document.body.classList.toggle('sidebar-mobile-show')
    }
  }

EDIT2: в другом потоке кто-то ответил, что, если логика функции тяжелая, она должна быть за пределами render (). Но зачем вам вообще нужна функция внутри render ()?

Насколько мне известно, все внутри render() постоянно зациклено.

ionizer 02.04.2018 19:53

@ionizer Я знаю это, но зачем вам функции, которые находятся внутри функции с непрерывным циклом?

yemerra 02.04.2018 19:55

divider называется лямбда-функцией или анонимной функцией. иногда вы хотите, чтобы он определял и использовал функцию только один раз. В этом случае я считаю, что вы можете легко переместить divider за пределы функции render (), поскольку он не ссылается ни на какие внешние переменные области видимости.

digitake 02.04.2018 19:59

Возможный дубликат Функция внутри рендера и класса в reactjs

illiteratewriter 02.04.2018 20:04

Извини за это. Что касается меня, я помещаю вещи в render, когда хочу, чтобы мой HTML или переменная автоматически обновлялась, с state или без нее.

ionizer 02.04.2018 20:05

@digitake Итак, вы говорите, что причиной наличия функций вне или внутри render () является область видимости?

yemerra 02.04.2018 20:41

@Goldi, да, это было бы для меня серьезной причиной.

digitake 02.04.2018 21:02

@digitake Думаю, это был бы ответ на мой вопрос. Я должен был видеть это раньше. Итак, если вы посмотрите на мою функцию hideMobile(): выполняет ли эта функция что-либо, что может быть сделано только вне функции render (), или лучше сделать это снаружи?

yemerra 02.04.2018 21:07

@Goldi, функция на мой взгляддекларация всегда лучше вне render(), дело в том, если вы должны вызов внутри render(), мой исходный ответ кажется не подходящим для вашего реального вопроса, я обновился, надеюсь, это помогло

Carr 03.04.2018 08:26
Поведение ключевого слова "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) для оценки ваших знаний,...
5
9
6 050
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Кроме того, handleClick - это функция, созданная и доступная для каждого объекта / компонента, а divide - это функция с локальной областью видимости, их функциональность может быть практически одинаковой. Однако divider будет создаваться как новая функция при каждом рендеринге, что в дальнейшем может повлиять на производительность, в то время как handleClick создается один раз для определенного компонента (объекта).

Что ж, я знал поведение, которое вы уже описываете, но я не знаю, почему вы хотите, чтобы это произошло. Не зная «почему», я бы предположил, что размещение функций внутри функции render () всегда плохо, поскольку render будет вызываться постоянно, и поэтому функции, которые находятся внутри render (), будут постоянно переопределяться.

yemerra 02.04.2018 19:57

@Goldi render will be called constantly - нет, а почему? только если вы передадите эту функцию как prop, тогда дочерний компонент всегда будет получать новую функцию - хотя на самом деле она не изменилась.

Tomasz Mularczyk 02.04.2018 20:11

Извините, это то, что я имею в виду под постоянным. Я имею в виду то, что вы описали. (на самом деле я имел в виду непрерывно)

yemerra 02.04.2018 20:39

render() вызывается каждый раз при смене state. Таким образом, каждая функция, которая хранится внутри функции рендеринга, будет создаваться как новая функция при каждом изменении state. Это означает, что divider будет создаваться заново каждый раз при повторном рендеринге.

handleClick - это обычная объектная функция.

Функции, написанные внутри функции render, обычно связаны с перерисовкой компонентов.

Не будет называться, если props поменяли.

Carr 02.04.2018 19:59
Ответ принят как подходящий

Из примера на официальный сайт:

Во-первых, если мы хотим создать Clock в самом начале, то таким образом мы пытались создать объектно-ориентированный, поддерживаемый компонент с функциональным объектом без состояния.

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
   ReactDOM.render(
     <Clock date = {new Date()} />,
     document.getElementById('root')
   );
}

setInterval(tick, 1000);

цитата из документа

to make the Clock component truly reusable and encapsulated. It will set up its own timer and update itself every second.

... Ideally we want to write this once and have the Clock update itself...

Итак, вот дух React, мы хотим преобразовать этот объект функции в класс, который мог бы поддерживать себя, поэтому теперь мы задействуем render(), а точнее, компонент с сохранением состояния:

Add a single empty method to it called render()
...
Clock is now defined as a class rather than a function.

Тогда получаем:

class Clock extends React.Component {
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
        this.clockCore = this.clockCore.bind(this);
    }

    componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
           1000
        );
     }

     tick() {
         this.setState({
             date: new Date()
         });
     }

     clockCore() {
         return (<div>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
         </div>);
     }

     render() {
        return this.clockCore();
     }
}

Как вы знаете, render() запускается снова и снова, если состояние компонента необходимо обновить с помощью setState().


Обновлять

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

Из приведенного вами примера использование разделителя может быть таким:

const divider = (divider, key) => {
  const classes = classNames( 'divider', divider.class);
  return (<li key = {key} className = { classes }></li>);
};

return (<ul>{this.state.dividerList?
    this.state.dividerList.forEach(divider) : null}</ul>);

Я думаю, что причина этого просто в ремонтопригодности, кто-то может захотеть, чтобы весь код создания DOM внутри render() для легкой трассировки, когда возвращаемая структура DOM действительно сложна (и стрелочная функция легкая), но, как я сказал, это субъективно, это действительно может быть определено снаружи.

В этом случае вместо этого используется Раньше я, и кажется, что то, что вы предоставили, более элегантно, но если вы определили эту функцию вне render(), это меня отвлекает.

let dividers = [];
if (this.state.dividerList) {
    this.state.dividerList.forEach((divider, key) => {
        let classes = classNames( 'divider', divider.class);
        dividers.push((<li key = {key} className = { classes }></li>));
    });
}

return (<ul>{dividers}</ul>);

Таким образом, другая функция, которую вы предоставили, которая нацелена на функцию манипуляций с DOM, полностью правильна и должна быть определена снаружи.

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