ใครที่ใช้ React แล้วเขียนด้วย Class Componentลองย้ายมาเขียน Functional Component (Hook) ดูน้า ไม่ยากเลย ทำให้โค๊ดอ่านง่ายมากขึ้นด้วย และเขียนง่ายขึ้น
วันนี้เอาตัวอย่างที่ใช้บ่อยๆ ใน React TypeScript เทียบกันให้เห็น จะๆ เลย
เราสามารถแปลงจาก Class Component ด้านล่างนี้
import React from 'react';
interface MyProps {
message: string;
};
interface MyState {
count: number;
};
class App extends React.Component<MyProps, MyState> {
state: MyState = {
// optional second annotation for better type inference
count: 0,
};
render() {
return (
<div>
{this.props.message} {this.state.count}
</div>
);
}
}
ให้เป็น Functional Component แบบนี้ได้
import React, { useState } from 'react';
interface PropTypes {
message: string;
}
function App({ message }: PropTypes){
const [count, setCount] = useState(0);
return (
<div>
{message} {count}
</div>
);
};
export default App;
ทำไมถึงไม่แนะนำ React.FC
หรือ React.FunctionComponent
/React.VoidFunctionComponent
อ่านรายละเอียดใน Functional Component
เราสามารถแปลงจาก Class Component ด้านล่างนี้
import React from 'react';
interface PropTypes {
message: string;
}
interface StateTypes {
counter: number;
}
class App extends React.Component<PropTypes, StateTypes> {
state: StateTypes = {
counter: 0
};
handleClick(amount: number) {
this.setState( state => ({
counter: state.counter + amount
}));
}
render() {
return (
<div>
<h1>{this.props.message}</h1>
<button onClick={() => this.handleClick(1)}> Increase </button>
<p>{this.state.counter}</p>
</div>
);
}
}
export default App;
Note: Using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison. Read more at React Official Doc.
ให้เป็น Functional Component แบบนี้ได้
import React, { useState } from 'react';
interface PropTypes {
message: string;
}
function App({ message }: PropTypes) {
const [counter, setCounter] = useState(0);
const handleClick = (amount: number) => {
setCounter(counter + amount);
};
return (
<div>
<h1>{message}</h1>
<button onClick={() => handleClick(1)}> Increase </button>
<p>{counter}</p>
</div>
);
};
export default App;
หนึ่งใน React Lifecyle ที่ใช้บ่อยๆ มากๆ คือ componentDidMount() ซึ่งจะทำครั้งแรก ครั้งเดียวเมื่อ Component โหลดเสร็จ
function FirstExecuteComponent() {
// add event listeners (Flux Store, WebSocket, document, etc.)
useEffect(
() => console.log("Component loaded"),
[]
);
return null;
}
ข้อสังเกตุ useEffect
ต้องการรับ 2 parameters ถ้าอยากให้เหมือน componentDidMount()
ให้ใส่ Array เปล่าๆ ใน parameters ตัวที่สอง []
อีกหนึ่งใน React Lifecyle ที่มีใช้บ้างคือคือ componentWillUnmount() ซึ่งจะทำงานครั้งสุดท้ายครั้งเดียวก่อนที่ 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 หรือล้างข้อมูลอะไรบางอย่าง ก็ได้ครับ
Cross published at .NET Thailand
Acknowledgement: Thank you .net thailand team to review this article: dotnetthailand.github.io#83