Hook 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能。 (from 官方文件)
並「函式」來複用邏輯的概念,重新設計元件,更新粒度更細,讓程式碼更清晰, 並逐步將 class component 替換成函式型元件 Function Component。,簡單來說就是沒有template的組件,方便用於狀態及邏輯覆用。
呼叫同個方法,給同樣的參數,永遠應該返回同樣的值,react 元件中,給相同的 props ,渲染的 ui應該永遠一樣,但副作用和純函數相反,還處理了和返回值無關的事。簡單來說副作用,會去觀測監測值的變化,來做指定的事。
const [count, setCount] = useState(0); useEffect(() => { document.title = `點擊${count}`; }, [count]);
P.S. useEffect 若不帶第二個參數,每次被渲染就會被調用,會造成無窮無死循環,若不想發生可以給他空 array。
P.S. useEffect watch 空 array 時,他只會初始化一次,在 Next JS 時可以當來用戶端初始化事件。
// promise 用法 const responses = fetch( "https://jsonplaceholder.typicode.com/users" ) .then(response => response.json()) .then(data => setRobotGallery(data))
或
// async await 用法 useEffect(() => { const fetchData = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/users"); const data = await res.json(); setRobotGallery(data); }; fetchData(); }, []);
const [loading, setLoading] = useState<boolean>(false);
{!loading ? ( <div className={styles.robotList}> {robotGallery.map((r) => ( <Robot key={r.id} id={r.id} email={r.email} name={r.name} /> ))} </div> ) : ( <h2>loading</h2> )}
const [error, setError] = useState<string>(); try { throw new Error("網站錯誤") } catch (e) { if (e instanceof Error) { setError(e.message); } } {(!error || error !== "") && <div>{error}</div>}
<component test="" /> add perpery props interface React.FC<props>
P.S. Prop Drilling 簡而言之是指:當一個元件自身不需要這個prop,但為了使子元件能獲取到這個prop,而不得已去傳遞這個prop的行為。
const defaultContextValue = { username: "阿來克斯", }; export const appContext = React.createContext(defaultContextValue); const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement ); root.render( <React.StrictMode> <appContext.Provider value={defaultContextValue}> <App /> </appContext.Provider> </React.StrictMode> );
使用的元件
import { appContext } from "../index"; <appContext.Consumer> {(value) => { return ( <div className={styles.cardContainer}> <p>{value.username}</p> </div> ); }} </appContext.Consumer>
onst Robot: React.FC<RobotProps> = ({ id, name, email }) => { const value = useContext(appContext) return ( <div className={styles.cardContainer}> <img alt="robot" src={`https://robohash.org/${id}`} /> <h2>{name}</h2> <p>{email}</p> <p>{value.username}</p> </div> ); };
P.S. 那麼如果,組件若不是上下級關係時,又不想一層層傳進去,則需要考慮用 redux 這種狀態管理的機制進行管理