React.js ดูบทช่วยสอนการจัดการสถานะ

เผยแพร่แล้ว: 2022-03-11

ปัญหาที่ใหญ่ที่สุดและพบบ่อยที่สุดประการหนึ่งในการพัฒนาเว็บส่วนหน้าคือการจัดการสถานะ นักพัฒนาฟรอนต์เอนด์อิสระเช่นฉันมักจะเน้นที่การทำให้อ็อบเจ็กต์สถานะซิงค์กับมุมมองและการแสดง DOM อย่างต่อเนื่อง ผู้ใช้สามารถโต้ตอบกับแอปพลิเคชันได้หลายวิธีและเป็นงานใหญ่ในการเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่งอย่างสมบูรณ์

ด้วยบทช่วยสอน React.js นี้ เรียนรู้เพิ่มเติมเกี่ยวกับการจัดการสถานะการดู

บิตของประวัติศาสตร์

ไม่นานมานี้ เว็บแอปพลิเคชันมีกระแสข้อมูลง่ายกว่ามาก เบราว์เซอร์จะส่งคำขอไปยังเซิร์ฟเวอร์ ตรรกะของแอปพลิเคชันทั้งหมดจะถูกดำเนินการบนเซิร์ฟเวอร์ และมุมมอง HTML แบบเต็มจะถูกส่งไปยังเบราว์เซอร์เพื่อนำเสนอต่อผู้ใช้ การกระทำของผู้ใช้ที่ตามมา (เช่น การคลิก การส่งแบบฟอร์ม ฯลฯ) จะทำให้เกิดโฟลว์เดียวกันอีกครั้ง แอปพลิเคชันไม่ต้องกังวลเกี่ยวกับสถานะผู้ใช้ และแต่ละมุมมองสามารถสร้างใหม่ได้โดยการส่งคำขอใหม่ไปยังเซิร์ฟเวอร์

อย่างไรก็ตาม เว็บแอปพลิเคชันมีความซับซ้อนมากขึ้น และความต้องการของผู้ใช้ UI/UX ก็ก้าวหน้าเช่นกัน การโหลดซ้ำทั้งหน้าเมื่อมีการเปลี่ยนแปลงเพียงส่วนเดียว ไม่ได้ผลและช้า เราต้องการการโต้ตอบที่รวดเร็ว ฉับไว และตอบสนองโดยมีผลกระทบทันทีบน UI

JavaScript เข้ามาช่วยเหลือ นักพัฒนาเริ่มเขียนโค้ดจำนวนมากซึ่งถูกดำเนินการในเบราว์เซอร์ก่อนที่จะส่งคำขอไปยังเซิร์ฟเวอร์ jQuery ยังนำความก้าวหน้าที่สำคัญมาสู่การพัฒนาเว็บส่วนหน้า เนื่องจากให้ความสามารถที่พร้อมใช้งานทันทีที่ใช้งานง่าย เช่น การตรวจสอบฝั่งไคลเอ็นต์ หน้าต่างโมดอล ข้อความแจ้งเตือน แอนิเมชั่น และแม้แต่การอัปเดตหน้าบางส่วนที่ใช้ Ajax

เข้าใจความซับซ้อน

มาดูตัวอย่างง่ายๆ ในการประเมินความแข็งแกร่งของรหัสผ่านกัน ถ้ารหัสผ่านใช้ได้ ช่องป้อนข้อมูลควรมีเส้นขอบสีเขียวและควรแสดงข้อความที่ดี หากรหัสผ่านไม่รัดกุม กล่องอินพุตควรมีขอบสีแดงและควรแสดงข้อความเตือน เราอาจแสดงหน้ายิ้มด้วยเมื่อรหัสผ่านแข็งแกร่งเพียงพอ

รหัสต่อไปนี้แสดงให้เห็นว่าสิ่งนี้สามารถทำได้โดยการจัดการ DOM มี "ifs" มากมายที่นี่ และโค้ดนี้อ่านได้ไม่ง่ายนัก

 if (hasInputBorder()) { removeInputBorder(); } if (text.length === 0) { if (hasMessage()) { removeMessage(); } if (hasSmiley()) { removeSmiley(); } } else { var strength = getPasswordStrength(text); if (!hasInputBorder()) { addInputBorder(); } var color = (strength == 'weak' ? 'red' : 'green'); setInputBorderColor(color); var message = (strength == 'weak' ? "Password is weak" : "That's what I call a password!"); if (hasMessage()) { setMessageText(message); } else { addMessageWithText(message); } if (strength == 'weak') { if (hasSmiley()) { removeSmiley(); } } else { if (!hasSmiley()) { addSmiley(); } } }

ดังที่แสดงไว้ด้านบน อันดับแรก เราต้องตรวจสอบว่าผู้ใช้ให้รหัสผ่านหรือไม่ และจัดการกับกรณีที่ฟิลด์รหัสผ่านว่างเปล่า และในทุกกรณี เราจำเป็นต้องตรวจสอบให้แน่ใจว่าองค์ประกอบ DOM ที่เกี่ยวข้องทั้งหมดได้รับการอัปเดตอย่างเหมาะสม ซึ่งรวมถึงข้อความ เส้นขอบ และหน้ายิ้ม

ฟิลด์รหัสผ่านของเราสามารถอยู่ในสถานะใดสถานะหนึ่งจากสามสถานะ: ว่างเปล่า อ่อนแอ หรือแข็งแกร่ง และตามที่ระบุไว้ เรามีองค์ประกอบ DOM ที่แตกต่างกันสามองค์ประกอบที่ได้รับผลกระทบจากสถานะช่องรหัสผ่าน การจัดการชุดค่าผสมทั้งหมด และตรวจสอบให้แน่ใจว่ามุมมองของเราแสดงอย่างถูกต้อง จะช่วยเพิ่มความซับซ้อนของวงจรสำหรับโค้ดธรรมดาๆ เช่นนี้

DOM ทำงานใน โหมดคงไว้ ซึ่งหมายถึงจำเฉพาะสถานะปัจจุบันเท่านั้น ในการแก้ไขมุมมองของเรา เราจำเป็นต้องจัดเตรียมคำแนะนำสำหรับองค์ประกอบ DOM แต่ละรายการและตั้งโปรแกรมการเปลี่ยนแปลง

การเปลี่ยนผ่านของการเข้ารหัสแทนที่จะเป็นสถานะอาจซับซ้อน จำนวนสาขาและการตรวจสอบที่เราจำเป็นต้องดำเนินการในโค้ดของเราเพิ่มขึ้นแบบทวีคูณด้วยจำนวนสถานะการดูที่ต้องจัดการ

ในตัวอย่างของเรา เรากำหนดสถานะการดูสามสถานะ ซึ่งทำให้เรามีการเปลี่ยนภาพ 3 * 2 = 6 ครั้ง โดยทั่วไป เมื่อกำหนดสถานะ N เรามีการเปลี่ยน N * (N - 1) = N^2 - N ที่เราจะต้องสร้างแบบจำลอง ลองนึกถึงความซับซ้อนที่เพิ่มขึ้นหากเราเพิ่มสถานะที่สี่ในตัวอย่างของเรา

โดยทั่วไปมีโค้ดที่เกี่ยวข้องกับการสร้างโมเดลการ เปลี่ยน มากเกินไป จะดีกว่ามากถ้าเราสามารถกำหนดสถานะการดูของเราและไม่ต้องกังวลกับรายละเอียดทั้งหมดของการเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่ง

ลดความซับซ้อน

สมมติว่าเราสามารถ ประกาศ สถานะการดูตามสถานะของโมเดล แทนที่จะเข้ารหัสการเปลี่ยนแปลงจากสถานะหนึ่งไปยังอีกสถานะหนึ่ง อย่างชัดเจน เราอาจมีสิ่งนี้:

 var strength = getPasswordStrength(text); if (text.length == 0) { return div(input({type: 'password', value: text})); } else if (strength == 'weak') { return div( input({type: 'password', value: text, borderColor: 'red'}), span({}, "Weak") ); } else { return div( input({type: 'password', value: text, borderColor: 'green'}), span({}, "That's what I call a password!"), img({class: 'icon-smiley'}) ); }

ที่นี่เรามีรหัสสามสาขาอย่างง่าย ซึ่งแสดงถึงสถานะที่เป็นไปได้สามประการของแอปของเรา เราเพียงแค่ส่งคืนข้อมูลจำเพาะของมุมมองในแต่ละสาขา ขึ้นอยู่กับสถานะของรุ่น รหัสการจัดการ DOM ทั้งหมดจะถูกลบออก เราแค่ให้ข้อมูลเกี่ยวกับ สิ่งที่ เราต้องการ ไม่ใช่ วิธี ไปถึงที่นั่น

แม้ว่าวิธีนี้จะลดความซับซ้อนของโค้ดลงได้อย่างมาก แต่ก็ถือว่ามีใครบางคนหรืออย่างอื่นที่จะดูแลการจัดการ DOM ที่เกิดขึ้นจริงในนามของเรา

นี่คือที่มาของ React React จะทำให้แน่ใจว่าสถานะการดูได้รับการจัดการและอัปเดตทันทีตามสถานะของแบบจำลองข้อมูลพื้นฐาน

ปฏิกิริยา

React คือไลบรารี JavaScript ที่สร้างโดย Facebook ออกแบบมาเพื่อจัดการส่วน UI ของเว็บแอปพลิเคชัน คุณสามารถคิดได้ว่าเป็น V ในสถาปัตยกรรม MVC มันเข้มข้นมาก ไม่มีการตั้งสมมติฐานเกี่ยวกับสแต็กเทคโนโลยีที่เหลือของคุณ และไม่ได้จัดการสิ่งอื่นใดนอกจากการเรนเดอร์ส่วนประกอบ ไม่มีกลไกการกำหนดเส้นทาง โมเดล หรือคุณลักษณะอื่นๆ ที่มักจะรวมอยู่ในเฟรมเวิร์กที่ใหญ่กว่า ดังนั้น คุณสามารถผสมมันและใช้กับไลบรารีหรือเฟรมเวิร์กอื่น ๆ ที่คุณต้องการได้

React ช่วยให้เราสามารถกำหนด UI เป็นแผนผังของส่วนประกอบแบบผสมได้ ผู้พัฒนา React กำหนดส่วนประกอบเหล่านั้นโดยการระบุ ฟังก์ชั่นการ เรนเดอร์ที่อธิบายส่วนประกอบ โดยกำหนดสถานะอินพุต ฟังก์ชันนั้นควร บริสุทธิ์ (เช่น ไม่ควรมีผลข้างเคียงหรือขึ้นอยู่กับสิ่งอื่นใดนอกจากอินพุตที่ชัดเจน)

ฟังก์ชันการแสดงผลส่งคืนคำอธิบายมุมมอง ซึ่ง React เรียก Virtual DOM คิดว่ามันเป็นวัตถุ JavaScript ที่สอดคล้องกับองค์ประกอบ DOM ที่แสดงผล

เมื่อคุณเปลี่ยนสถานะของส่วนประกอบ มันจะแสดงผลตัวเองและองค์ประกอบย่อยทั้งหมดอีกครั้ง โดยจะส่งคืน Virtual DOM ใหม่

นอกจากนี้ React จะไม่ทำการแทนที่ HTML อย่างง่าย เมื่อเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่ง จะค้นหาความแตกต่างระหว่างสถานะก่อนหน้าและสถานะใหม่ และคำนวณชุดการดำเนินการ DOM ที่มีประสิทธิภาพสูงสุดเพื่อดำเนินการเปลี่ยน

แม้จะไม่ได้คำนึงถึงประสิทธิภาพ ความซับซ้อนของโค้ดที่ลดลงก็มีความสำคัญและทำให้เราสามารถมุ่งเน้นความพยายามของเราในส่วนที่มีเอกลักษณ์และซับซ้อนมากขึ้นของแอปพลิเคชันของเรา

เพื่อให้ชัดเจนขึ้นอีกเล็กน้อย นี่คือตัวอย่างบทช่วยสอนของเราที่จะทำโดยใช้ React เพื่อจัดการสถานะการดู

หมายเหตุ: ตัวอย่างโค้ดต่อไปนี้เขียนด้วยตัวประมวลผลล่วงหน้า JSX ซึ่งเป็นวิธีทั่วไปในการเขียน UI ที่ใช้ React

 function getPasswordStrength(text) { // Some code that calculates the strength given the password text. } var PasswordWithStrength = React.createClass({ getInitialState: function() { return {value: ''}; }, render: function() { var strength = getPasswordStrength(this.state.value); if (this.state.value.length == 0) { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} /> </div>; } else if (strength == 'weak') { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} style={ {border: '1px solid red'} } /> <span style={{color: 'red'}}>Weak!</span> </div>; } else { return <div> <input type="password" value={this.state.value} onChange={this.handleInputChange} style={ {border: '1px solid green'} } /> <span style={{color: 'green'}}>That's what I call a password!</span> <Emoji value="smiley" /> </div>; } }, handleInputChange: function(ev) { this.setState({value: ev.target.value}); } }); React.render(<PasswordWithStrength />, document.body);

องค์ประกอบ Emoji ที่แสดงผลเมื่อระดับความปลอดภัยของรหัสผ่านใช้ได้ โดย <Emoji value="smiley" /> เป็นเพียงองค์ประกอบที่กำหนดเองอีกส่วนหนึ่ง (เช่นเดียวกับ PasswordWithStrength ) ถูกกำหนดดังนี้:

 var Emoji = React.createClass({ render: function() { var emojiSrc = this.props.value + '.png'; return <img src={emojiSrc}></img>; } });

React.js กับคนอื่น ๆ

อย่างไรก็ตาม ในความเป็นธรรม ยังมีเฟรมเวิร์ก JavaScript ฝั่งไคลเอ็นต์อื่นๆ (เช่น Ember, Angular, Knockout และอื่นๆ) ที่แก้ไขปัญหาการจัดการสถานะการดูด้วย และเพิ่มฟีเจอร์เพิ่มเติมเข้าไปด้วย เหตุใดคุณจึงต้องการใช้ React แทนเฟรมเวิร์กอื่น ๆ

มีข้อดีหลักสองประการที่ React มี เมื่อเทียบกับไลบรารีอื่นๆ ส่วนใหญ่

ไม่มีการผูกข้อมูล

เฟรมเวิร์กทางเลือกอื่นๆ บางตัวใช้การโยงข้อมูลเพื่อแมปองค์ประกอบ DOM กับคุณสมบัติของรัฐ และรักษาข้อมูลให้ตรงกันโดยสังเกตการเปลี่ยนแปลงของคุณสมบัติ วิธีการนี้ช่วยให้แสดงผลมุมมองเพียงครั้งเดียว โดยการเปลี่ยนแปลงแต่ละครั้งจะทริกเกอร์การแก้ไของค์ประกอบ DOM ที่ได้รับผลกระทบเท่านั้น ทางเลือกอื่นใช้การ ตรวจสอบสกปรก นั่นคือ แทนที่จะสังเกตการเปลี่ยนแปลงของคุณสมบัติแต่ละอย่าง พวกเขาเพียงแค่แสดงความแตกต่างระหว่างสถานะก่อนหน้าและสถานะใหม่ React คล้ายกับวิธีการแบบหลังมากกว่า แต่แทนที่จะเปรียบเทียบสถานะ มันจะเปรียบเทียบการแสดงแทนมุมมอง

React ไม่มีการผูกข้อมูล นักพัฒนาต้องเรียกใช้เมธอด setState หรือแสดงผลคอมโพเนนต์บนสุดอีกครั้ง เมื่อสถานะมีการเปลี่ยนแปลง มันโอบรับการไหลแบบทิศทางเดียว จากรัฐสู่มุมมอง

แนวคิดนี้ง่ายต่อการนำไปใช้ เนื่องจากโดยทั่วไปแล้วนักพัฒนาจะไม่คำนึงถึงการเชื่อมโยงข้อมูล โฟกัสอยู่ที่การแสดงข้อมูลด้วยภาพ ดังนั้นคุณจึงไม่ต้องนึกถึงคุณสมบัติที่ขึ้นต่อกัน การจัดรูปแบบ การผูกแท็ก HTML พิเศษ ฯลฯ ด้วย React คุณเพียงแค่แสดงผลองค์ประกอบใหม่เมื่อโมเดลเปลี่ยนแปลง

เพื่อทำความเข้าใจความแตกต่างในการจัดการสถานะการดูที่นี่ ให้เปรียบเทียบ Ember และ React เราจะสร้างวัตถุ person จะแสดงชื่อเต็มเป็นตัวพิมพ์ใหญ่ หลังจากสองวินาที เราจะจำลองการเปลี่ยนแปลงและอัปเดตมุมมอง

 // EXAMPLE USING EMBER App = Ember.Application.create(); App.Person = Ember.Object.extend({ firstName: null, lastName: null, fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); var person = App.Person.create({ firstName: "John", lastName: "Doe" }); Ember.Handlebars.helper('upcase', function(value) { return value.toUpperCase(); }); App.IndexRoute = Ember.Route.extend({ model: function () { return person; } }); setTimeout(function() { person.set('firstName', 'Harry'); }, 2000); // Templates: <script type="text/x-handlebars"> <h2>Welcome to Ember.js</h2> {{outlet}} </script> <script type="text/x-handlebars" data-template-name="index"> The current user is: {{upcase model.fullName}} </script>

เราสร้างวัตถุด้วยคุณสมบัติ firstName , fullName และ lastName เนื่องจาก Ember กำลังสังเกตการเปลี่ยนแปลงคุณสมบัติ เราจึงต้องระบุว่า fullName ขึ้นอยู่กับ firstName และ the lastName ในการทำเช่นนี้ เราได้เพิ่ม .property('firstName', 'lastName') เมื่อเรากำหนด fullName

หลังจากผ่านไปสองวินาที person.set('firstName', 'Harry'); ถูกดำเนินการ สิ่งนี้ทำให้เกิดการอัปเดตมุมมองและการเชื่อมโยง

ตอนนี้ ลองทำแบบเดียวกันใน React

 // EXAMPLE USING REACT var CurrentUser = React.createClass({ render: function() { return <div>The current user is: {this.props.user.fullName().toUpperCase()}</div>; } }); var person = { firstName: 'John', lastName: 'Doe', fullName: function() { return this.firstName + ' ' + this.lastName; } }; var currentUser = React.render(<CurrentUser user={person}/>, document.body); setTimeout(function() { person.firstName = 'Harry'; currentUser.setProps({user: person}); }, 2000);

แม้ว่ารหัส Ember จะเรียบง่ายและอ่านง่าย แต่ก็ชัดเจนว่า React ชนะอย่างเรียบง่าย person นั้นเป็นออบเจกต์ JavaScript ธรรมดา โดยที่ชื่อ fullName เป็นเพียงฟังก์ชัน

ไม่มีแม่แบบ

กรอบงานทางเลือกแต่ละแบบมีวิธีการจัดการแม่แบบที่แตกต่างกัน บางตัวใช้สตริงที่คอมไพล์เป็น JavaScript ในขณะที่บางตัวใช้องค์ประกอบ DOM โดยตรง ส่วนใหญ่ใช้แอตทริบิวต์และแท็ก HTML ที่กำหนดเองซึ่งจะถูก "คอมไพล์" เป็น HTML

เทมเพลตไม่ได้เป็นส่วนหนึ่งของโค้ด JavaScript ด้วยเหตุนี้ แต่ละทางเลือกจึง ต้องการ วิธีการที่กำหนดเองเพื่อแสดงถึงการดำเนินการทั่วไป เงื่อนไข การวนซ้ำ การเรียกใช้ฟังก์ชัน ฯลฯ ทั้งหมดนี้จบลงด้วยการสร้างภาษาเทียมใหม่ที่นักพัฒนาต้องเรียนรู้

ไม่มีเทมเพลตใน React ทุกอย่างเป็นเพียง JavaScript แบบเก่าธรรมดา

React ใช้พลังเต็มรูปแบบของ JavaScript เพื่อสร้างมุมมอง วิธีการเรนเดอร์ของคอมโพเนนต์คือฟังก์ชัน JavaScript

JSX พร้อมใช้งานในฐานะตัวประมวลผลล่วงหน้าที่เปลี่ยน “รูปแบบคล้าย HTML” ให้เป็น JavaScript ปกติ แต่ JSX เป็นทางเลือก และคุณสามารถใช้ JavaScript มาตรฐานได้โดยไม่ต้องมีตัวประมวลผลล่วงหน้า คุณยังสามารถใช้ประโยชน์จากเครื่องมือ JavaScript ที่มีอยู่ได้อีกด้วย Linters, ตัวประมวลผลล่วงหน้า, คำอธิบายประกอบประเภท, การลดขนาด, การกำจัดโค้ดที่ไม่ทำงาน ฯลฯ

ลองใช้ตัวอย่างที่เป็นรูปธรรมอีกครั้งเพื่อเปรียบเทียบ React กับหนึ่งในกรอบงานทางเลือกสำหรับการจัดการสถานะการดู

บทช่วยสอนต่อไปนี้เป็นตัวอย่างของการใช้ AngularJS เพื่อแสดงรายการแฮชแท็กและจำนวนทวีตสำหรับแต่ละรายการ รายการจะถูกจัดเรียงตามจำนวน และข้อความจะปรากฏขึ้นหากไม่มีแฮชแท็ก

 <!-- EXAMPLE USING ANGULAR --> <div ng-controller="MyCtrl"> <ul ng-show="hashTags.length > 0"> <li ng-repeat="hashTag in hashTags | orderBy:'tweetCount':true"> {{hashTag.name}} - {{hashTag.tweetCount}} tweets </li> </ul> <span ng-show="hashTags.length == 0">No hashtags found!</span> </div>

เพื่อให้สามารถสร้างรายการนี้ได้ นักพัฒนาต้องเรียนรู้เกี่ยวกับ AngularJS directives , ng-show และ ng-repeat จากนั้นเขาต้องเรียนรู้เกี่ยวกับ AngularJS filters เพื่อทำความเข้าใจ orderBy การทำงานง่ายๆ เช่น การออกรายการ ต้องใช้ความพยายามอย่างมาก!

ตอนนี้ มาลองพิจารณาตัวอย่าง React ที่ทำสิ่งเดียวกัน:

 // EXAMPLE USING REACT function byTweetCountDesc(h1, h2) { return h2.tweetCount - h1.tweetCount; } //... render: function() { if (this.state.hashTags.length > 0) { var comps = this.state.hashTags.sort(byTweetCountDesc).map(function(hashTag, index) { return <li key={index}> {hashTag.name} - {hashTag.tweetCount} tweets </li>; }); return <ul>{comps}</ul>; } else { return <span>No hashtags found!</span> } }

แม้ว่าเราจะใช้แนวทาง "ขั้นสูงกว่า" และ JSX นักพัฒนาเว็บทุกรายที่มีความเข้าใจพื้นฐานของ JavaScript สามารถอ่านโค้ดด้านบนและทำความเข้าใจกับสิ่งที่ทำได้อย่างง่ายดาย การตรวจสอบตามเงื่อนไขมาตรฐานโดยใช้ if , การวนซ้ำโดยใช้ map() และ 'sort()' มาตรฐานนั้นเป็นเรื่องปกติสำหรับนักพัฒนา ดังนั้นจึงไม่มีไวยากรณ์เพิ่มเติมหรือแนวคิดอื่น ๆ ให้เรียนรู้

บทสรุป

ประเด็นหลักจากบทช่วยสอน React.js นี้คือความจริงที่ว่า React ช่วยให้คุณมุ่งเน้นไปที่การจัดการสถานะการดูจริงมากกว่าการเปลี่ยน ซึ่งจะทำให้งานและแอปพลิเคชันของคุณง่ายขึ้น

เส้นโค้งการเรียนรู้สำหรับการนำ React มาใช้นั้นค่อนข้างไม่สำคัญ ไม่มีภาษาเทมเพลตที่กำหนดเองให้เชี่ยวชาญ ไม่มีการเชื่อมโยงข้อมูลที่ต้องกังวล และทุกอย่างมาจากฟังก์ชัน JavaScript ที่อธิบายองค์ประกอบ UI

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการลดความซับซ้อนของโค้ดแอปพลิเคชันของคุณโดยใช้ React ให้ดูที่การพูดคุยนี้โดย Steven Luscher ซึ่งเป็น Decomplexifying Code with React

นี่คือบางส่วนการอ่านเพิ่มเติมสำหรับทุกคนที่ต้องการดำเนินการขั้นตอนต่อไปและเริ่มใช้ React:

  • http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome