React JS Logo

React Lv.2 JSX และการทำงานของมัน

Prutya Kunaroob
2 min readAug 27, 2017

--

ต่อจากคราวที่แล้วกันเลยละกันครับ ตอนนี้เราก็รู้หมดละว่าเรามีอะไรในโฟลเดอร์โปรเจ็คของเราบ้าง ในวันนี้เรามาโฟกัสกันที่การทำงานของ React กันสักหน่อยดีกว่าครับ

JSX เบื้องหน้า

เป็นส่วนเสริมพิเศษของ JavaSript ที่ทำให้เราเขียน Mark Up ได้ในไฟล์ JS เลย ดังนี้

const hello = <h1>Hello</h1>

ซึ่งถ้าเป็นปกติแล้วเราจะพิมแบบนี้ไม่ได้ แต่อย่าห่วงครับเราได้อัพเกรดให้มันโดยใช้ babel ไปเรียบร้อยละ

เนื่องจาก JSX เขียนอยู่บนไฟล์ JS ทำให้ได้เปรียบกว่าภาษาอื่นๆในการที่จะนำค่าต่างๆไปคำนวณ เข้า function ต่างๆ ก่อนที่จะมาแสดงผลด้วย Html ได้อย่างง่ายๆ

// using name to compute, evaluation, etc. before render
const name = evaluateName('T');
// Using name it in JSX
const hello = <h1>{name}</h1>
// หรือจะเขียนแบบนี้
const hello = <h1>{evaluateName('T')}</h1>
// wrap ใส่ใน function ก็ได้ ใช้ if else ด้วยยังได้
function hello (name) {
if (name) {
return <h1>Hello {name}</h1>
}
return <h1>Hello George</h1>
}

การสื่อสารหลักๆ ระหว่างตัวแปรที่โยนเข้าไปใน JSX ก็คือผ่าน {} ปีกกา คล้ายๆกับ Mark Up ในภาษาอื่นๆ อย่าง Vue, Angular ซึ่งในนี้จะโยน expression เข้าไปได้หมด ไม่ว่าจะเป็นการเรียกใช้ function การคำนวณ หรือโยนตัวแปร โยน String เข้าไปตรงๆก็ได้

สำหรับใครที่อยากดูตัวอย่างการใช้ if-else ในการ render กดเข้าไป official docs นี้เลยครับ

Note อีกอย่าง เวลาเราจะใส่ class ให้ JSX เนี่ย ไม่สามารถเขียนแบบนี้ได้

<h1 class="greeting">Hello</h1>

เพราะว่า class มันเป็น reserved word ของ JavaScript ซึ่งถูกใช้ในการประกาศ JavaScript Class ดังนั้น JSX เลยให้เราใช้คำว่า className แทน แก้ให้ถูกต้องเขียนแบบนี้ครับ

<h1 className="greeting">Hello</h1>

JSX เบื้องหลัง

<h1 className="greeting">Hello</h1>

เรามาดูการทำงานเบื้องหลังของ JSX กันดีกว่า ซึ่งจากที่เราเขียน

const hello = <h1 className="greeting">Hello</h1>

เจ้า babel ก็จะทำการแปลโค้ดด้านบนให้กลายเป็นคำสั่ง JavaScript

React.createElement(
'h1',
{ className: 'greeting' },
'Hello, world!'
);

สังเกตุเห็นไหมครับ ตอนแปลงจะมีการใช้งาน React.createElement เพราะฉะนั้น ทุกครั้งที่เราจะเขียน JSX เราต้องทำการ import React from 'react' เข้ามาก่อนทุกครั้งนะครับ งั้นมันจะแปลงเป็น JavaScript Object แบบด้านบนไม่ได้

ในระหว่างนี้ React ก็จะช่วยเช็ค Syntax ของโค้ด JSX ที่เราเขียน ว่ามีข้อผิดพลาดอะไรไหม ถ้าหากทุกอย่างราบรื่น ผลลัพท์ของโค้ดที่แปลงแล้วจะได้ Object หน้าตาประมาณนี้ออกมา

const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};

ชื่อของ Object ผลลัพท์ เรียกว่า React Element พอได้เจ้าก้อนนี้ออกมาก็หมดหน้าที่ของ React แล้ว แต่การที่จะสร้าง DOM ออกมาเป็น UI ให้เราเห็นนั้น มันยังต้องการตัวช่วย ในการแปล React Element ออกมาเป็น DOM อยู่ ซึ่งเจ้าตัวที่ว่านี่ก็คือ ReactDOM ครับ

ReactDOM

ก่อนอื่นมาเปิดโปรเจ็คเรากันก่อนครับดูไฟล์ตั้งต้น index.js กันให้ไว

นี่ไงครับบรรทัดที่ 2 มีการ import ReactDOM เข้ามา

และก็ในบรรทัดที่ 7 เจ้า ReactDOM ก็ทำการ render วาด UI จาก ReactElement <App /> ไว้บนน element id #root ที่เราได้ประกาศทิ้งไว้ในไฟล์ public/index.html นั่นเองครับ

ข้อดีของการมี ReactElement นั้นช่วยให้ React ไม่ต้องวาด UI ใหม่ทั้งหน้าทุกครั้งที่มีการอัพเดท ก่อนที่ ReactDOM จะทำการวาด UI ทุกครั้งมันจะเช็ค ReactElement ตัวปัจจุบัน กับตัวก่อนหน้า ว่ามันมีจุดแตกต่างกันตรงไหนบ้าง แล้วมันก็จะเช็คละดึงเอาแต่ส่วนที่มีการอัพเดท มาวาดใหม่เท่านั้น

การทำแบบนี้ทำให้ไม่ต้องไปเปลือง resource ในการวาด UI ในส่วนที่ไม่จำเป็นได้พอสมควร อีกทั้งยังช่วยในเรื่องความเร็วของการแสดงผลด้วยครับ

วิธีการตามด้านบนนี้ ผมเดานะมันน่าจะเป็นการใช้ Shadow DOM (ReactElement) ชิงเช็คตอนเป็น Object ธรรมดาที่กินทรัพยากรน้อยกว่า ตัว DOM จริงๆ ก่อนจะวาดเฉพาะส่วนที่จำเป็นนั่นเองครับ

ตัวอย่างด้านล่างนี้เอามาจาก Render-Elements Official Docs ครับผม เพื่อให้เห็นภาพการ Render เฉพาะส่วนของ ReactDOM

ภาพตัวอย่างการ Render เฉพาะส่วนของ ReactDOM

ขอบคุณทุกท่านที่ติดตามอ่านกันนะครับ นี่เป็นเนื้อหาที่สามารถอ่านใน Offiical Docs ได้ครับ แต่ผมเอามาสรุปตามแบบของผมให้มันง่ายขึ้น และต้องขออภัยในการดองบทความด้วยนะครับ ฮ่าๆ

ไว้คราวหน้าเราจะมาดูว่าการใช้ Css Framework ต่างๆไม่ว่าจะเป็น Bootstrap, Bulma กับทาง React ต้องทำไง พร้อมกับการเซ็ต Eslinter Code Style Guide จาก Airbnb มาช่วยเตือนตอนเราเขียนโค้ดครับ แล้วเจอกันใหม่ตอนหน้าครับ

--

--