با این شروع میکنیم که JSX یا JavaScript XML یک سینتکس هست که بهمون این امکان رو میده که کد html و javascript رو باهم بنویسیم یا به عبارت دیگه ساختار XML رو شبیه HTML میکنه.
اما مرورگر این کد jsx رو نمیخونه و یطورایی باید براش ترجمه بشه و کد رو به ( )React.createElement تبدیل کنه که این تبدیل میتونه استفاده از TypeScript باشه یا با استفاده از مفسر Babel.
ساده ترین راهش استفاده و نصب ابزار create-react-app هست که خودش این تبدیل کد رو انجام میده و بانصب اون Babel هم نصب میشه که بتونه کد React رو بخونه و تبدیل به ES5 کنه و در نهایت تو مرورگر اجرا بشه.
حالا اگه بخواهیم المنت اضافه کنیم ولی نه از طریق jsx باید چیکار کنیم ؟
یک راه قدیمی که توصیه نمیشه اینه که هردفعه که میخواهیم المنت ایجاد کنیم از React.createElement استفاده کنیم که سینتکسش به صورت زیره:
React.createElement(type,{props},children);
اما یک مثال آشنا بزنیم واسش:
import React from 'react'; const Example = () => { return React.createElement('h1', { style: { color:'black' } }, 'Hello World'); }; ReactDOM.render(React.createElement(Example), document.getElementById('root'));
اما خب اینجا همه چی خوب بود پس دیگه چرا jsx اومد جایگزین این روش شد؟
اولا که هردفعه که بخواهیم یک المنت جدید اضافه کنیم باید از یک React.createElement جدید استفاده کنیم که کارمون رو سخت میکنه هم چنین کدش اصلا خوانا نیست و خوندش سختتره.
برای درک بهتر تفاوت های بالا به نوشتن همون کد بالا با jsx دقت کنید:
import React from 'react' function Example() { return ( <div> <h1>Hello World</h1> </div> ) } export default Example
خب کد بالا خیلی خواناتره همونطور که مشخصه..
حالا کد jsx چطوری توسط مرورگر ترجمه میشه؟
بالا گفتیم به یک مفسر نیاز هست که کد jsx رو به جاوا اسکریپت اصلی که مرورگر میتونه بخونه ترجمه کنه اصطلاحا، که این مفسر اسمش Babel هست.
عکس زیر شاید بتونه بهتر مفهوم رو منتقل کنه ^ _ ^
اصلا Babel چی هست؟
مفسر یا ابزار Babel به شما اجازه میده که با جدیدترین سینتکس جاوا اسکریپت کد بزنید یا از فریم ورک ها و کتابخونه هایی مثل React استفاده کنید چون در صورت نبود Babel، خیلی از مرورگر ها نمیتونن این کد هارو بخونن و مرورگر فقط نسخه ES5 جاوا اسکریپت رو میتونه بخونه و کدشو اجرا کنه.
خلاصش اینه که Babel خودش میاد از createElement استفاده میکنه و این تبدیل رو انجام میده و دیگه نیازی نیست که مثل روش قدیمی بالا خودمون هردفعه که میخواهیم المنت ایجاد کنیم از createElement استفاده کنیم.
نمونه ی کد jsx زیر رو در نظر بگیرید میخواهیم ببینیم babel اینو چطوری ترجمه میکنه.
import React from 'react' function App (){ return ( <div> <p>This is a list</p> <ul> <li>List item 1</li> <li>List item 2</li> </ul> </div> ); };
اینجا Babel میاد jsx رو به شکل زیر کامپایل میکنه و اول از تابع createElement استفاده میکنه.
import React from 'react' function App() { return React.createElement( 'div', null, React.createElement('p', null, 'This is a list'), React.createElement( 'ul', null, React.createElement('li', null, 'List item 1'), React.createElement('li', null, 'List item 2'))); }
الان این تابع ابجکت زیر رو بر میگردونه که کدش plain javascript هست یعنی سینتکس جاوا اسکریپت بدون کتابخونه و فریم ورک، جاوا اسکریپت خام هست کدش اصطلاحا.
{ 'type': 'div', 'key': null, 'ref': null, 'props': { 'children': [ { 'type': 'p', 'key': null, 'ref': null, 'props': { 'children': 'This is a list' }, '_owner': null }, { 'type': 'ul', 'key': null, 'ref': null, 'props': { 'children': [ { 'type': 'li', 'props': { 'children': 'List item 1' }, }, { 'type': 'li', 'props': { 'children': 'List item 2' }, } ] }, '_owner': null } ] }, '_owner': null }
ریکت میاد از این ابجکت استفاده میکنه و المنت هارو از روش میخونه و به virtual Dom اضافه میکنه و بعدش به Dom اصلی اضافه میشه.
برای توضیح بیشتر المنت هاشو یکی یکی معرفی میکنیم:
حالا اگر بخوهیم کد jsx رو بدون استفاده و یا import کردن ریکت بنویسم باید چکار کنیم؟
تو ورژن React v17. 0 این امکان به ما داده شده که بدون 'import React from 'react ما میتونیم کد jsx بنویسیم یعنی دیگه اون فرایند تبدیل به createElement و اینا رو نداره .
مثال زیر یک نمونه از نوشتن متن Hello world به این روش هست:
import {jsx as _jsx} from 'react/jsx-runtime'; function App() { return _jsx('h1', { children: 'Hello world' }); }
در ادامه چند تا ازقوانین و سینتکسی که باید رعایت بشه تو jsx رو معرفی میکنیم:
چطوری میتونیم چند تا jsx اضافه کنیم؟؟
import React from 'react' import ReactDOM from 'react-dom' const App = () => { return ( <p>This is first JSX Element!</p> <p>This is another JSX Element</p> ); }; const rootElement = document.getElementById('root'); ReactDOM.render(<App />, rootElement);
البته شما اگه الان بیاد این کد رو اجرا کنید ارور میده ، چرا؟
چون باید تگ های شما یک والد داشته باشن حتما توریکت یعنی به شکل زیر :
import React from 'react' import ReactDOM from 'react-dom' const App = () => { return ( <div> <p>This is first JSX Element!</p> <p>This is another JSX Element</p> </div> ); }; const rootElement = document.getElementById('root'); ReactDOM.render(<App />, rootElement);
البته یک راه دیگه هم که هست اینه که از fragment ها تو ریکت استفاده کنید یعنی به شکل زیر:
import React from 'react' import ReactDOM from 'react-dom' const App = () => { return ( <> <p>This is first JSX Element!</p> <p>This is another JSX Element</p> </> ); }; const rootElement = document.getElementById('root'); ReactDOM.render(<App />, rootElement);
این راه جدیدتره و استفاده ازش توصیه میشه کارتون و استایل دهی به تگ ها رو راحتتر میکنه.
چطوری از کد javascript در jsx استفاده کنیم؟
کد مربوط به javasccript باید تو اکولاد قرار بگیره تا خونده شه :
const App = () => { const number = 10; return ( <div> <p>Number: {number}</p> </div> ); };
حالا تو این اکولاد چیا میتونه قرار بگیره :
چیا نمیتونن قرار بگیرن تو jsx؟
**موارد پایین عموما میرن بالای برنامه قبل از return قرار میگیرن نه jsx**
مفهوم jsx و استفاده از اون از موارد حیاتی برای یادگیری ریکت هست و هم چنین ازش در مصاحبه های فرانت زیاد سوال میشه که خوندن مطالب بالا میتونه کمک کننده باشه.