[react] React常用的JavaScript語法 - 可選鏈
JavaScript
要是我們並不清楚取得的資料是否為物件,又使用物件取值的方式去呼叫,且沒有做任何的判斷,程式就會報出錯誤:
index.js
let food = null;console.log(food.name); // error : Cannot read properties of null (reading 'name')
所以判斷一個物件裡面有沒有我們要取得的 key,可以使用以下方法來確認:
index.js
let food = { name: "apple" };if (food != null) { console.log(food.name); // output : apple}// orif (food) { console.log(food.name); // output : apple}
或是使用可選鏈(optional chaining),來檢查該物件內是否有我們要取得的 key:
index.js
let food = { name: "apple" };if (food?.name) { console.log(food.name); // output : apple}//不會進到這個if 因為food物件內並沒有名為color的keyif (food?.color) { console.log(food.color);}
備註
可選鏈的使用方式為在物件名稱的後面加上 ?.
而 food?.name 為檢查 food 物件內有沒有名為 name 的 key。
假釋今天物件內有其他 function,可以使用可選鏈先確認 function 是否存在,存在的話再執行它:
index.js
let food = { name: "apple", color: "red", getFoodData: () => { console.log("getFoodData..."); // output : getFoodData... },};food?.getFoodData?.();
React
現在使用 fetch API 來取得 jsonplaceholder 的提供的 posts 資料,並把 limit 設置為 5,這樣我們每次 fetch 只會取得 5 筆 post 的資料。
App.js
function App() { const [posts, setPosts] = useState(null); useEffect(() => { const getPostData = async () => { const response = await fetch( "https://jsonplaceholder.typicode.com/posts?_limit=5" ); const data = await response.json(); setPosts(data); }; getPostData(); }, []); console.log(posts); // output : (5) [{…}, {…}, {…}, {…}, {…}] return ( <div className="App"> {posts.map((post) => ( <p>{post.title}</p> ))} </div> );}
但使用上面的寫法只要重新整理網頁後,程式就會報出錯誤,這是因為 posts 這個 state 在初始化時為 null,而 null 這個型態並沒有支援 map function,所以才會出現錯誤訊息。
而我們可以在程式中加上判斷,判斷 posts 是否為 null,如果是的話就回傳 Loading 文字。
App.js
function App() { const [posts, setPosts] = useState(null); useEffect(() => { const getPostData = async () => { const response = await fetch( "https://jsonplaceholder.typicode.com/posts?_limit=5" ); const data = await response.json(); setPosts(data); }; getPostData(); }, []); console.log(posts); if (posts == null) { return <h1>Loading...</h1>; } return ( <div className="App"> {posts.map((post) => ( <p>{post.title}</p> ))} </div> );}
或是直接在 posts 後面加上可選鏈,這樣就不用撰寫多餘的判斷程式碼:
App.js
function App() { const [posts, setPosts] = useState(null); useEffect(() => { const getPostData = async () => { const response = await fetch( "https://jsonplaceholder.typicode.com/posts?_limit=5" ); const data = await response.json(); setPosts(data); }; getPostData(); }, []); console.log(posts); // output : (5) [{…}, {…}, {…}, {…}, {…}] return ( <div className="App"> {posts?.map((post) => ( <p>{post.title}</p> ))} </div> );}