[鐵人賽 2022-擊敗前端面試大作戰] React Hooks
今天要來聊 React hooks,Hooks 在 React 16.8 推出,它提供了更低的學習曲線、更高的可讀性和更輕鬆的 debug。這篇文章會預設你已經看過 react 的hooks 文章,並且對 hooks 有基本的了解,然後我們會以面試的問答方式來討論幾個常見的 hooks!
- hooks 的規則?
回答:hooks 有兩個規則,第一個是 hooks 只能在最高層被呼叫,代表 hooks 不能在 if condition, function 等情況下呼叫。第二個是 hooks 只能在 React functional component 或是 custom hooks 中呼叫,不能在 Js function 中使用。
follow up: 為什麼 hooks 只能在最高層被呼叫?
回答:因為 React 依靠 hooks 呼叫的順序。
https://reactjs.org/docs/hooks-rules.html#explanation
- useEffect 執行順序,console.log 結果是什麼?
function Test({ name, children = null }) {
console.log("children", children);
useEffect(() => {
console.log(`${name} effect`);
return () => {
console.log(`${name} cleanup`);
};
});
return children;
}
function App() {
return (
<Test name="parent">
<Test name="child">123</Test>
</Test>
);
}
範例在這
解題思路:在 React 16 中,mount 的順序是父組建 => 子組建,effect 的順序是子組建 => 父組建。
注意:child render 兩次,因為使用 strict mode 中並且在 dev 環境中,實際 prod 環境只會 render 一次。
- useRef,console.log 結果會是什麼?
function App() {
const ref = useRef(null);
const [state, setState] = useState(1);
useEffect(() => {
setState(2);
}, []);
console.log("text", ref.current?.textContent);
return (
<div>
<div ref={state === 1 ? ref : null}>1</div>
<div ref={state === 2 ? ref : null}>2</div>
</div>
);
}
範例在[這](https://codesandbox.io/s/objective-wood-hqxpqx?file=/src/App.js:111-413)
解題思路:ref 有兩個重點,
- ref 的值不會因為 re-render 而變動。
- 更新 ref 的值也不會造成 re-render。
follow up,如果把 useEffect 裡面的[]拿掉,結果會改變嗎?
如果對 useRef 還是有點不熟悉的話,筆者很推這篇文章,我覺得他用很淺顯的字句把 useRef 的用途講得很仔細!
- 什麼是 useImperativeHandle?
解題思路:useImperativeHandle 可以讓父組件輸出任意數據,其必須要和 forwardRef 一起使用。
下面看範例:
透過 useImperativeHandle,我們讓父層可以控制子層的 focus。
// 透過forwardRef 讓FancyInput组件可以接收ref
const FancyInput = React.forwardRef(function FancyInput(props, ref) {
const inputRef = useRef();
// 命令式的给`ref.current`focus
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus()
}
}));
return <input ref={inputRef} ... />
})
// Example组件作为父组件
function Example() {
const fancyInputRef = useRef()
const focus = () => {
fancyInputRef.current.focus()
}
return (
<>
<FancyInput ref={fancyInputRef} />
</>
)
}
希望這些題目,能夠讓讀者對 hooks 有一些更深的理解,hooks 的應用有非常多,在短短一篇的篇幅實在是講不完,這裡筆者只是列出幾個我覺得蠻有趣的例子,其他部分就等讀者自己去研究摟~~~
https://juejin.cn/post/7094651577117442056 https://segmentfault.com/a/1190000040758640 https://beta.reactjs.org/learn/state-as-a-snapshot