React Design Pattern
Import & Export (JavaScript modules)
Default export
// MyComponent.tsxconst MyComponent = () => <div>Hey, MyComponent</div>;export default MyComponent;// App.tsximport MyComponent from './MyComponent';Export
// MyComponent.tsxexport const MyComponent = () => <div>Hey, MyComponent</div>;// App.tsximport { MyComponent } from './MyComponent';Rename import
// MyComponent.tsxexport const MyComponent = () => <div>Hey, MyComponent</div>;// App.tsximport { MyComponent as MySuperComponent } from './MyComponent';export const App = () => <MySuperComponent />;Group all imports and rename
// MyComponent.tsxexport const Switch = () => <div>Hey, Switch</div>;export const Group = () => <div>Hey, Group</div>;// App.tsximport { * as MyComponent } from './MyComponent';export const App = () => (<><MyComponent.Switch /><MyComponent.Group /></>);Re-export all
// MyComponent.tsxexport const Switch = () => <div>Hey, Switch</div>;export const Group = () => <div>Hey, Group</div>;// MyParentComponent.tsxexport * from "./MyComponent";// App.tsximport { Switch, Group } from './MyParentComponent';export const App = () => (<><Switch /><Group /></>);Re-export, then group all imports and rename
// MyComponent.tsxexport const Switch = () => <div>Hey, Switch</div>;export const Group = () => <div>Hey, Group</div>;// MyParentComponent.tsxexport * as MyComponent from "./MyComponent";// App.tsximport { MyComponent } from './MyParentComponent';export const App = () => (<><MyComponent.Switch /><MyComponent.Group /></>);Export type
// MyComponent.tsxexport type Gender = "Male" | "Female"; // Accept only "Male" or "Female"// App.tsximport { Gender } from './MyComponent'Export interface
// MyComponent.tsxexport interface IUser {id: string;name: string;}// App.tsximport { IUser } from './MyComponent'
Handling with side effects
Side effects เป็น function โดยส่วนใหญ่แล้ว เราจะจัดการกับ Side Effect ของ Component โดยมี 3 scenarios:
- ทำงานเฉพาะครั้งแรกที่ Component mount (Only when a component mounts)
- เคลียร์ค่าต่างๆ โดยใช้ return a function (Cleaning up by returning a function)
- ทำงานเมื่อ dependencies มีการเปลี่ยนแปลง (Running when specific dependencies change)a
ทำงานเฉพาะครั้งแรกที่ Component mount
จะทำครั้งแรก ครั้งเดียวเมื่อ Component โหลดเสร็จ
function FirstExecuteComponent() {// Add event listeners (Flux Store, WebSocket, document, etc.)useEffect(() => console.log("Component loaded"),[]);return null;}
ข้อสังเกตุ useEffect
ต้องการรับ 2 parameters ถ้าอยากให้เหมือน componentDidMount()
ให้ใส่ Array เปล่าๆ ใน parameters ตัวที่สอง []
เคลียร์ค่าต่างๆ โดยใช้ return a function
จะทำงานครั้งสุดท้ายครั้งเดียวก่อนที่ Component ถูกเอาออก (Component is unmounted and destroyed)
function FirstAndLastExecuteComponent() {// Remove event listeners (Flux Store, WebSocket, document, etc.)useEffect(() => {console.log("Component loaded");return () => console.log("Component unloaded");},[]);return null;}
เราสามารถใช้ประโยชน์จาก function useEffect
ได้ ตรงที่ return ของ parameters ตัวแรกของ useEffect
โดยเราสามารถ remove event listeners หรือล้างข้อมูลอะไรบางอย่าง ก็ได้ครับ
ตัวอย่างการเคลียร์ค่า EventListener ของ Window Resize
import React, { useState, useEffect } from "react";function getWindowSize() {return {width: window.innerWidth,height: window.innerHeight};}export default function WindowSize() {const [size, setSize] = useState(getWindowSize());useEffect(() => {const handleResize = () => {setSize(getWindowSize());}window.addEventListener("resize", handleResize);return () => window.removeEventListener('resize', handleResize);}, []);return (<p>Width: {size.width}, Height: {size.height}</p>);}
ทำงานเมื่อ dependencies มีการเปลี่ยนแปลง
เราสามารถใส่ dependencies ที่อยากตรวจสอบได้ เช่น เมื่อ toggle มีการเปลี่ยนแปลงค่า จากที่ User เป็นคนคลิก ให้เรียก side effect เป็นต้น ดังตัวอย่างข้างล่างนี้
import React, { useState, useEffect } from "react";export default function DetectChange() {const [toggle, setToggle] = useState(false);const [message, setMessage] = useState("");useEffect(() => {const toggleMessage = toggle ? "True" : "False";setMessage(toggleMessage);}, [toggle]);return (<p><button onClick={() => setToggle(!toggle)}>Toggle</button><h1>{message}</h1></p>);}
Note: ตัวอย่างนี้ไม่ใช่วิธีการที่ดีในการควบคุม state เขียนอธิบายการทำงานเท่านั้น
Style Guide
Read more in Airbnb's Style guide
Other Resources
Other topics can read in below resources: