Что может находиться в render кроме return?
Просматривая разные примеры вижу, что часто люди в render() хранят логику компонента: частично или полностью. Допустим у нас есть дефолтный компонент:
export default class App extends PureComponent {
state = {
...
};
...
render() {
...
return (
<div>
{app}
</div>
)
}
}
Какая логика может храниться в render()? Насколько она может быть сложной?
Ответы (2 шт):
Не советую что нибудь там хранить.
Книга React в действии стр. 60 пункт 2.2.5 Метод рендеринга
Второй абзац:
Метод render должен возвращать только один элемент React.
Внимание на ключевое слово должен.Метод render всегда должен быть и оставаться чистой.Плохая практика делать там сайд эффекты либо вызывать setState.(Во втором случае либо ваш код попадет в бесконечный цикл либо покажет вот такое предупреждения
Warning: Cannot update during an existing state transition (such as within render).
Render methods should be a pure function of props and state.
Что также говорит о том что метод render должен быть чистой функцией.
Также в render нельзя получить доступ к UI элементам.
render() {
// Вот так делать вообще не стоит
const node = ReactDOM.findDOMNode(nodeElement);
Получите ошибку:
Warning: Person is accessing getDOMNode or findDOMNode inside its render().
render() should be a pure function of props and state
Логика которая можно использовать в render по моему опыту это условный рендеринг.
render(){
if(this.state.viewMode === "night"){
return <Night />
} else {
return <Day />
}
}
Хотя и эту логику в идеале нужно выносить в отдельную функцию и вызывать внутри return
renderMode() {
if(this.state.viewMode === "night"){
return <Night />
} else {
return <Day />
}
}
render(){
return (
<>
<h3>Hi there</h3>
{this.renderMode()}
</>
)
}
Логика влияющая на "содержимое" возвращаемое return
Обычно в render получают значения state, обрабатывают их так, чтобы использовать в "содержимом" возвращаемым return
Можно также использовать конструкцию с несколькими return
if(this.state.loaded) {
return
<div>
{app}
</div>
} else {
return
<div>
Loading
</div>
}