Я только начал изучать 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 ()?
@ionizer Я знаю это, но зачем вам функции, которые находятся внутри функции с непрерывным циклом?
divider называется лямбда-функцией или анонимной функцией. иногда вы хотите, чтобы он определял и использовал функцию только один раз. В этом случае я считаю, что вы можете легко переместить divider за пределы функции render (), поскольку он не ссылается ни на какие внешние переменные области видимости.
Возможный дубликат Функция внутри рендера и класса в reactjs
Извини за это. Что касается меня, я помещаю вещи в render, когда хочу, чтобы мой HTML или переменная автоматически обновлялась, с state или без нее.
@digitake Итак, вы говорите, что причиной наличия функций вне или внутри render () является область видимости?
@Goldi, да, это было бы для меня серьезной причиной.
@digitake Думаю, это был бы ответ на мой вопрос. Я должен был видеть это раньше. Итак, если вы посмотрите на мою функцию hideMobile(): выполняет ли эта функция что-либо, что может быть сделано только вне функции render (), или лучше сделать это снаружи?
@Goldi, функция на мой взгляддекларация всегда лучше вне render(), дело в том, если вы должны вызов внутри render(), мой исходный ответ кажется не подходящим для вашего реального вопроса, я обновился, надеюсь, это помогло



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


Кроме того, handleClick - это функция, созданная и доступная для каждого объекта / компонента, а divide - это функция с локальной областью видимости, их функциональность может быть практически одинаковой. Однако divider будет создаваться как новая функция при каждом рендеринге, что в дальнейшем может повлиять на производительность, в то время как handleClick создается один раз для определенного компонента (объекта).
Что ж, я знал поведение, которое вы уже описываете, но я не знаю, почему вы хотите, чтобы это произошло. Не зная «почему», я бы предположил, что размещение функций внутри функции render () всегда плохо, поскольку render будет вызываться постоянно, и поэтому функции, которые находятся внутри render (), будут постоянно переопределяться.
@Goldi render will be called constantly - нет, а почему? только если вы передадите эту функцию как prop, тогда дочерний компонент всегда будет получать новую функцию - хотя на самом деле она не изменилась.
Извините, это то, что я имею в виду под постоянным. Я имею в виду то, что вы описали. (на самом деле я имел в виду непрерывно)
render() вызывается каждый раз при смене state. Таким образом, каждая функция, которая хранится внутри функции рендеринга, будет создаваться как новая функция при каждом изменении state. Это означает, что divider будет создаваться заново каждый раз при повторном рендеринге.
handleClick - это обычная объектная функция.
Функции, написанные внутри функции render, обычно связаны с перерисовкой компонентов.
Не будет называться, если props поменяли.
Из примера на официальный сайт:
Во-первых, если мы хотим создать 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, полностью правильна и должна быть определена снаружи.
Насколько мне известно, все внутри
render()постоянно зациклено.