Reactjs-də component-lərin iki dəfə render olması problemi və həlli.

Kamil Abiyev
3 min readOct 24, 2020

Bu problemin baş verməsinin səbəbi React.StrictMode-un bir xüsusiyyətidir. Əslində bu sadəcə development mode-da baş verir və əsas məqsədi isə render mərhələsində baş verə biləcək yan təsirlərin qarşısının alınmasıdır.

Fərqli misallar üzərində bunu müşahidə etmək mümkündür.

A) useState ilə yazılmış functional component-ə nəzər salaq.

function App() {
const [click, setClick] = React.useState(0);console.log('Render edildi ', click);
return (
<div>
<button onClick={() => setClick(click => click + 1)}>
Clicks: {click}
</button>
</div>
)
}

Əgər create-react-app istifadə edərək react app yaratsaq və npm start ilə çalışdırsaq browser console-da aşağıdakı output-la qarşılaşacağıq.

Render edildi 0
Render edildi 0

Əgər button-a bir dəfə click-ləsək belə bir output-la qarşılaşacağıq.

Render edildi 1
Render edildi 1

Bunun səbəbi index.js faylındakı React.StrictMode köməkçi tool-dur.

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

<React.StrictMode> -u silsək problemin həll olacaq və npm start --port 3001 ilə yeni port üzərindən çalışdırsaq browser console-da belə bir output-la qarşılaşacağıq.

Render edildi 0
Render edildi 1

B) useState əvəzinə useReduce istifadə edək.

useState yerinə useReduceişlətdim və nəticə dəyişmədi:

function App() {
const [clicks, dispatch] = React.useReducer((state, action) => {
switch (action.type) {
case 'click':
return state + 1;
default:
throw new Error()
}
}, 0)console.log('Render edildi ', clicks);
return (
<div >
<button onClick={()=>dispatch({type:'click'})}>
Clicks: {clicks}
</button>
</div>
)
}

Browser console:

Render edildi 0
Render edildi 0
Render edildi 1
Render edildi 1

C) Class Component

Functional Component əvəzinə Class Component istifadə etdikdə də eyni problemlə qarşılaşdığımızı görürük.

class App extends React.Component {
render() {
console.log('Render edildi');
return null;
}
}

Browser console:

Render edildi

Bəs burada nə baş verir ki biz bu problemlə qarşılaşırıq?

Əsas səbəb 16.3.0 versiyası ilə birlikdə təqdim edilən React.StrictMode -dur. Bu versiyadan əvvəl köməkçi tool sadəcə class component-lər üçün istifadə edilə bilirdi. 16.8.0 versiyasının gəlişi ilə bu tool hooks üçün də istifadə edilə bilən hala gəldi.

Applikasiyada potensial problemləri vurğulayan alətlərdən biri StrictMode-dur. StrictMode, Fragment kimi heç bir görünən UI render etmir. Bu alət sadəcə descendants üçün əlavə yoxlamalar edərək xəbərdarlıqlar göstərir. ‒ rəsmi React sənədi

StrictMode aşağıdakı problemlər üçün faydalıdır:

Strict rejim avtomatik olaraq belə yan effektləri aşkar edə bilmir. Amma, bu rejim ilə yan effektlərin olduğu yerləri tapmaq mümkündür. Bu yan effektlərin tapılması üçün aşağıdakı funksiyalar iki dəfə çağrılır:

  • Sinif komponentinin constructor, rendershouldComponentUpdate funksiyaları
  • Sinif komponentinin statik getDerivedStateFromProps metodu
  • Funksiya komponentinin gövdələri
  • State yeniləyici funksiyalar (setState funksiyasının ilk arqumenti)
  • useState, useMemouseReducer-ə göndərilən funksiyalar

Niyə React.StrictMode istifadə edilməlidir?

React qısa müddət sonra Concurrent Mode adlı eksperimenti təqdim edəcək. Bu eksperiment, React applikasiyalarına responsive qalmağa, istifadəçinin cihaz imkanlarına və şəbəkə sürətinə düzgün cavab verməyə kömək edən yeni xüsusiyyətlər toplusudur.

--

--

Kamil Abiyev

Software Developer, Founder and Editor of Star Gazers