New React Hook, React.use

Milk Midi
4 min readFeb 27, 2023

--

大家好,我是奶綠
最近在研究 Next.js 13,發現官方的範例使用到了一個新的 React.use 函式,深入追下去後,發現這是 React 下一版將加入的新 hook,他可以讓我們用更少的程式碼來 fetch Data。

因為新版還沒發佈,所以先需要手動將 React 升級到 18.3.xxxx 版。

先來看目前怎麼使用 React 來 fetch data。

import React from "react";

export default function Example() {
const [data, setData] = React.useState([]);
const [isLoading, setLoading] = React.useState(true);

React.useEffect(() => {
fetch("someUrl")
.then((res) => res.json())
.then(setData)
.finally(() => {
setLoading(false);
});
}, []);

return (
<section data-name="Example1">
{isLoading && <div>LOADING</div>}
<ul>
{data.map((d) => {
return <li key={d.id}>{d.text}</li>;
})}
</ul>
</section>
);
}

二個 state,一個記錄結果,一個用來判斷是否在 loading,再搭配 useEffect 時,呼叫 API。

React.use

來看看新的 React.use 是怎麼實作的。

import React from "react";

const fetchData = () => {
return fetch("someUrl").then((res) => res.json());
};
const promiseFetchData = fetchData();
const TodoData = () => {
// React.use
// const data = React.use(fetchData()); // !!! Warning 這樣會無限 loop
const data = React.use(promiseFetchData);
return (
<section data-name="TodoData">
<ul>
{data.map((d) => {
return <li key={d.id}>{d.text}</li>;
})}
</ul>
</section>
);
};

export default function Example() {
return (
<section data-name="Example2">
<React.Suspense fallback={<div>LOADING</div>}>
<TodoData />
</React.Suspense>
</section>
);
}

直接在 Component 裡使用 React.use(這裡放Promise 物件),這裡要注意喔,不能直接放函式

const data = React.use(fetchData()); // !!! Warning 這樣會無限 loop
// 因為 fetchData 完成後,該 Component 又會 rerender,然以後又呼叫一次 fetchData
// 又 rerender。

// 改成這樣即可
const promiseFetchData = fetchData();
const data = React.use(promiseFetchData);

要知道是否在 loading 的話,只需要在父元件使用 React.Suspense 即可。

過去是 Component 先 mounted 後,才打 API。
而使用 React.use 則是先打 API,才建立 Component。

是不是使用上變的很簡單呀,當然如果 fetchData 要傳參數的話,需要再包裝一下。

附上原始碼,祝大家

--

--