React.Component — основна класа за креирање компонената коришћењем наслеђивања у React-у. Пре појаве хук-ова у верзији 16.8, класни компоненти су били једини начин управљања стањем и животним циклусом. Према React, 2024, класни компоненти се и даље подржавају, иако се функционални са хук-овима препоручују за нове пројекте.
Главне тачке
React.Component — апстрактна класа која пружа уграђене методе за рад са стањем, пропсима и животним циклусом компонента. Да бисте креирали класни компонент, потребно је дефинисати класу која наслеђује React.Component и имплементирати метод render.
React.Component се појавио у првој верзији React-а (2013) и остао је главни начин креирања компонената пет година. Екосистем React-а се градио око класа: компоненти вишег реда (HOC), render props, контекст — сви ови обрасци су имплементирани кроз класну синтаксу.
Са издавањем React 16.8 у 2019. години, React тим је представио хук-ове као алтернативу класама. Хук-ови су решавали исте задатке — стање, ефекти, контекст — али без наслеђивања и сложеног везивања контекста. React.Component остаје потпуно подржан, али се за нове пројекте препоручује функционални приступ.
Минимални класни компонент — класа са јединим методом render који враћа React елемент. render — једина обавезна метода. Мора бити чиста функција од this.props и this.state: исти скуп пропса и стања даје исти резултат.
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Конструктор се извршава пре монтирања. У њему се позива super(props) за прослеђивање пропса родитељској класи и иницијализује се this.state. Коришћење конструктора у друге сврхе — претплате, API позиви — не препоручује се: за то постоји componentDidMount.
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return <p>Count: {this.state.count}</p>;
}
}
this.state — објекат који садржи податке компонента. Директно мењање (this.state.count = 1) је забрањено — не изазива поновно рендеровање и нарушава предвидљивост. Стање се ажурира кроз this.setState, који креира нови објекат стања и покреће поновно рендеровање.
setState може примити објекат или функцију. Функционална форма је пожељнија када ново стање зависи од претходног: this.setState(prev => ({ count: prev.count + 1 })). React може груписати више setState позива у један batch ради оптимизације перформанси.
class Toggle extends Component {
constructor(props) {
super(props);
this.state = { isOn: false };
}
handleClick() {
this.setState(prev => ({ isOn: !prev.isOn }));
}
render() {
return (
<button onClick={() => this.handleClick()}>
{this.state.isOn ? 'ON' : 'OFF'}
</button>
);
}
}
Важно својство setState — он је асинхрон. Након позива setState, стање се не ажурира тренутно. Ако је потребно извршити радњу након ажурирања, проследите callback као други аргумент: this.setState(newState, () => console.log(this.state)).
Класни компоненти имају предефинисане методе које React позива у одређеним тренуцима. Монтирање — constructor → render → componentDidMount. Ажурирање — render → componentDidUpdate. Демонтирање — componentWillUnmount.
| Метода | Фаза | Намена |
|---|---|---|
| constructor | Монтирање | Иницијализација state-а и везивање метода |
| render | Сваки пут | Враћање React елемената (обавезно) |
| componentDidMount | Након монтирања | API захтеви, претплате, тајмери |
| componentDidUpdate | Након ажурирања | Реакција на промену пропса/стања |
| componentWillUnmount | Пре уклањања | Чишћење претплата, тајмера, одјава са догађаја |
componentDidMount — главно место за нуспојаве након првог рендеровања. Овде се извршавају HTTP захтеви, успостављају WebSocket везе и покрећу тајмери. Ако не очистите претплату у componentWillUnmount, долази до цурења меморије.
class UserProfile extends Component {
componentDidMount() {
fetch(`/api/users/${this.props.userId}`)
.then(res => res.json())
.then(data => this.setState({ user: data }));
}
componentWillUnmount() {
// Откажи захтев при демонтирању
}
render() {
return <div>{this.state.user?.name}</div>;
}
}
У JavaScript-у, методе класе подразумевано нису везане за инстанцу. Ако проследите методу као callback — руковаоцу догађаја, тајмеру — this ће бити undefined (у стриктном режиму) или window (без стриктног режима). Без везивања, this.setState ће бацити грешку.
Постоје три начина везивања: bind у конструктору, стреличаста функција у callback-у и class field са стреличастом функцијом. Први начин — званична препорука React-а: bind једном у конструктору, без поновног креирања функције при сваком рендеровању.
// Метода 1: bind у конструктору (препоручено)
class MyComponent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ clicked: true });
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}
Class field — модерна синтакса са аутоматским везивањем. Стреличаста функција у својству класе хвата this из опсега видљивости конструктора. Недостатак — метода се креира на свакој инстанци, а не на прототипу, што повећава меморију за стотине компонената истог типа.
Избор између класе и функције — није само питање синтаксе. Функционални компоненти са хук-овима решавају проблеме својствене класама: дуплирање логике у различитим методама животног циклуса (componentDidMount + componentDidUpdate), сложеност са this и немогућност издвајања повезане логике у блок за поновну употребу.
Функционалне компоненте је лакше тестирати — оне немају унутрашње стање (које је пре хук-ова било само у класама) и не захтевају монтирање у DOM за проверу callback-ова. React препоручује функционалне компоненте за све нове пројекте, документација и примери се пишу на њима.
Класни компоненти остају најбољи избор за рад са старим кодом. Ако је пројекат започет пре 2019. године, вероватно садржи хиљаде класних компонената. Преписивање свих у хук-ове у једном спринту је ризично. React гарантује уназадну компатибилност: класни компоненти неће бити уклоњени.
Постепена миграција почиње анализом компонента. Једноставни компоненти без стања (stateless) преводе се први — они се тривијално замењују функцијама. Затим — компоненти са једним-два поља стања, где useState директно замењује this.state и this.setState.
Сложени компоненти са више метода животног циклуса преводе се кроз useEffect. Логика из componentDidMount + componentDidUpdate се дели на одвојене useEffect-ове са различитим зависностима. componentWillUnmount се замењује функцијом повратка унутар useEffect-а. За сложену логику стања користите useReducer.
Алати за аутоматску миграцију — @phenomnomnominal/ts-react-class-to-hook или codemod скриптови — могу аутоматски конвертовати једноставне класе. За сложене случајеве, миграција остаје ручни рад који захтева разумевање логике оригиналног компонента.
Често постављана питања
Да. super(props) прослеђује пропсе родитељском React.Component-у. Без овог позива, this.props ће бити undefined унутар конструктора. У render-у и методама животног циклуса, пропси су доступни чак и без super, али је то нуспојава имплементације.
React групише више setState позива у један batch ради смањења броја непотребних поновних рендеровања. Да је setState синхрон, сваки позив би изазвао тренутно рендеровање, смањујући перформансе при масовним ажурирањима.
Не. Хук-ови раде само у функционалним компонентима. За пројекте са класним компонентима доступни су сви стари обрасци: render props, HOC и Consumer за контекст. Миграција на хук-ове захтева трансформацију класе у функцију.
React.PureComponent имплементира shouldComponentUpdate са плитким (shallow) поређењем пропса и стања. За разлику од Component-а, који увек поново рендерује при setState, PureComponent прескаче поновно рендеровање ако се подаци нису променили. Ово је оптимизација за компоненте без сложеног угњежђења.
Користите componentDidCatch и getDerivedStateFromError. componentDidCatch(error, info) бележи грешку. getDerivedStateFromError ажурира state за приказ fallback-UI. Ове методе раде само у класним компонентима — функцијама је потребан ErrorBoundary омотач.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође