本教程將教您如何使用 Axios 獲取數(shù)據(jù),然后如何操作它并最終通過過濾功能將其顯示在您的頁面上。您將在此過程中學(xué)習如何使用映射、過濾器和包含方法。最重要的是,您將創(chuàng)建一個簡單的加載器來處理從 API 端點獲取的數(shù)據(jù)的加載狀態(tài)。
1. 設(shè)置項目
讓我們在終端中使用 create-react-app 命令設(shè)置一個 React 項目:
npx create-react-app project-name
然后,通過終端窗口打開項目目錄,輸入 npm install axios 在本地為項目安裝 Axios。
2.選擇目標API
我們將使用隨機用戶生成器 API 來獲取隨機用戶信息以在我們的應(yīng)用程序中使用。
讓我們將 Axios 模塊添加到我們的應(yīng)用程序中,方法是將其導(dǎo)入到我們的 App.js 文件中。
import axios from 'axios'
隨機用戶生成器 API 提供了一系列用于創(chuàng)建各種類型數(shù)據(jù)的選項。您可以查看文檔以獲取更多信息,但對于本教程,我們將保持簡單。
我們想要獲取十個不同的用戶,我們只需要名字、姓氏和唯一的 ID,這是 React 創(chuàng)建元素列表時所需要的。另外,為了使調(diào)用更加具體,我們以國籍選項為例。
下面是我們將調(diào)用的 API URL:
https://randomuser.me/api/?results=10&inc=name,registered&nat=fr
請注意,我沒有使用 API 中提供的 id 選項,因為它有時會為某些用戶返回 null 。因此,為了確保每個用戶都有一個唯一的值,我在 API 中包含了 registered 選項。
您可以將其復(fù)制并粘貼到瀏覽器中,您將看到返回的 JSON 格式的數(shù)據(jù)。
現(xiàn)在,接下來就是通過 Axios 進行 API 調(diào)用。
3. 創(chuàng)建應(yīng)用程序狀態(tài)
首先,讓我們使用 React 中的 useState 掛鉤創(chuàng)建狀態(tài),以便我們可以存儲獲取的數(shù)據(jù)。
在我們的 App 組件中,從 React 導(dǎo)入 useState 鉤子,然后創(chuàng)建如下所示的狀態(tài)。
import React, { useState } from "react"; import axios from "axios"; const App = () => { const [users, setUsers] = useState([]); const [store, setStore] = useState([]); return ( <div> </div> ); }; export default App;
在這里你可以看到 users 和 store 狀態(tài)。一個將用于過濾目的,不會被編輯,另一個將保存將在 DOM 中顯示的過濾結(jié)果。
4.使用axios獲取數(shù)據(jù)
接下來我們需要做的是創(chuàng)建一個 getUsers 函數(shù)來處理數(shù)據(jù)的獲取。在此函數(shù)中,我們使用 axios 使用 get 方法從 API 獲取數(shù)據(jù)。
現(xiàn)在,為了在頁面加載時顯示我們獲取的數(shù)據(jù),我們將導(dǎo)入一個名為 useEffect 的 React hook,并在其中調(diào)用 getUsers 函數(shù)。
useEffect 鉤子基本上管理功能組件中的副作用,它類似于 React 基于類的組件中使用的 componentDidMount() 生命周期鉤子。該鉤子接受一個空數(shù)組作為第二個參數(shù),以進行副作用清理。
更新 App 組件中的代碼,如下所示,以便我們可以在控制臺中檢查響應(yīng)數(shù)據(jù)。
import React, { useState, useEffect } from "react"; const App = () => { const [users, setUsers] = useState([]); const [store, setStore] = useState([]); const getUsers = () => { axios.get("https://randomuser.me/api/?results=10&inc=name,registered&nat=fr") .then(response => console.log(response)) }; useEffect(() => { getUsers(); }, []); return ( <div> </div> ); }; export default App;
當您檢查控制臺時,您將看到一個對象輸出。如果你打開這個對象,里面有另一個對象,名為 data,而在 data 里面,有一個名為 results 的數(shù)組。
如果我們想從結(jié)果中返回特定值,我們可以更新 axios.get 調(diào)用,如下所示:
axios.get("https://randomuser.me/api/?results=10&inc=name,registered&nat=fr") .then(response => console.log(response.data.results[0].name.first))
這里我們記錄了結(jié)果數(shù)組中第一個值的名稱。
5.處理結(jié)果數(shù)據(jù)
現(xiàn)在讓我們使用 JavaScript 內(nèi)置的 map 方法來迭代數(shù)組中的每個元素,并創(chuàng)建一個具有新結(jié)構(gòu)的新 JavaScript 對象數(shù)組。
使用以下代碼更新您的 getUsers 函數(shù):
const getUsers = () => { axios .get("https://randomuser.me/api/?results=10&inc=name,registered&nat=fr") .then((response) => { const newData = response.data.results.map((result) => ({ name: `${result.name.first} ${result.name.last}`, id: result.registered })); setUsers(newData); setStore(newData); }) .catch((error) => { console.log(error); }); };
在上面的代碼中,我們創(chuàng)建了一個名為 newData 的變量。它存儲使用 map 方法查看 response.data.results 數(shù)組的結(jié)果。在 map 回調(diào)中,我們將數(shù)組的每個元素引用為 result (注意單數(shù)/復(fù)數(shù)差異)。此外,通過使用數(shù)組中每個對象的鍵值對,我們使用 name 和 id 鍵值對創(chuàng)建了另一個對象。
一般情況下,在瀏覽器中查看API調(diào)用結(jié)果,會看到里面有first 和last 鍵值對name 對象,但沒有全名的鍵值對。因此,從上面的代碼中,我們能夠組合 first 和 last 名稱,在新的 JavaScript 對象中創(chuàng)建全名。請注意,JSON 和 JavaScript 對象是不同的東西,盡管它們的工作方式基本相同。
然后我們將新的中間數(shù)據(jù)設(shè)置為 setUsers 和 setStore 狀態(tài)。
6. 通過過濾填充數(shù)據(jù)存儲
過濾的想法非常簡單。我們有我們的 store 狀態(tài),它始終保持原始數(shù)據(jù)不變。然后,通過在該狀態(tài)上使用 filter 函數(shù),我們只獲取匹配的元素,然后將它們分配給 users 狀態(tài)。
const filteredData = store.filter((item) => ( item.name.toLowerCase().includes(event.target.value.toLowerCase()))
filter 方法需要一個函數(shù)作為參數(shù),該函數(shù)針對數(shù)組中的每個元素運行。這里我們將數(shù)組中的每個元素稱為 item。然后,我們獲取每個 item 的 name 鍵并將其轉(zhuǎn)換為小寫,以使我們的過濾功能不區(qū)分大小寫。
獲得 item 的 name 鍵后,我們檢查該鍵是否包含我們輸入的搜索字符串。 includes 是另一個內(nèi)置 JavaScript 方法。我們將在輸入字段中鍵入的搜索字符串作為參數(shù)傳遞給 includes,如果該字符串包含在調(diào)用它的變量中,則它會返回。同樣,我們將輸入字符串轉(zhuǎn)換為小寫,這樣無論您輸入大寫還是小寫輸入都無關(guān)緊要。
最后,filter方法返回匹配的元素。因此,我們只需將這些元素存儲在 setUsers 狀態(tài)中即可。
使用我們創(chuàng)建的函數(shù)的最終版本更新 App 組件。
const filterNames = (event) => { const filteredData = store.filter((item) => item.name.toLowerCase().includes(event.target.value.toLowerCase()) ); setUsers(filteredData); };
7. 創(chuàng)建組件
盡管對于這個小示例,我們可以將所有內(nèi)容放入 App 組件中,但讓我們利用 React 并制作一些小型功能組件。
讓我們向應(yīng)用程序添加幾個組件。首先,我們從單獨的 JavaScript 文件導(dǎo)入組件(我們將很快定義這些文件):
import Lists from "./components/Lists"; import SearchBar from "./components/SearchBar";
接下來,我們更新應(yīng)用程序組件的 return 語句以使用這些組件:
return ( <div classname="Card"> <div classname="header">NAME LIST</div> <searchbar searchfunction="{filterNames}"></searchbar><lists usernames="{users}"></lists> </div> );
目前,我們將只關(guān)注功能。稍后我將提供我創(chuàng)建的 CSS 文件。
請注意,我們有 searchFunction 屬性用于 SearchBar 組件,以及 usernames 屬性用于 Lists 組件.
另請注意,我們使用 users 狀態(tài)而不是 store 狀態(tài)來顯示數(shù)據(jù),因為 users 狀態(tài)包含已過濾的數(shù)據(jù)結(jié)果。
SearchBar 組件
這個組件非常簡單。它僅將 filterNames 函數(shù)作為 prop,并在輸入字段更改時調(diào)用該函數(shù)。將以下代碼放入 components/SearchBar.js 中:
import React from 'react'; const SearchBar = ({ searchFunction}) => { return ( <div> <input classname="searchBar" type="search" onchange="{searchFunction}"> </div> ) }; export default SearchBar;
列表組件
該組件將簡單地列出用戶的姓名。這位于 components/List.js 中:
import React from 'react'; const Lists = ({ usernames }) => { return ( <div> <ul> {usernames.map(username => ( <li key="{username.id}">{username.name}</li> ))} </ul> </div> ) }; export default Lists;
在這里,我們再次使用 map 方法來獲取數(shù)組中的每個項目,并從中創(chuàng)建一個
8.跟蹤加載狀態(tài)
讓我們使用 useState 掛鉤創(chuàng)建一個加載狀態(tài),以顯示何時尚未獲取數(shù)據(jù)。
const [loading, setLoading] = useState(false);
接下來,我們將更新數(shù)據(jù)獲取方法中的加載狀態(tài)。
const getUsers = () => { axios.get("https://randomuser.me/api/?results=10&inc=name,registered&nat=fr") .then((response) => { const newData = response.data.results.map((result) => ({ name: `${result.name.first} ${result.name.first}`, id: result.registered, })); setLoading(true); setUsers(newData); setStore(newData); }) .catch((error) => { console.log(error); }); };
在這里,我們創(chuàng)建了一個 loading 狀態(tài)并將其初始設(shè)置為 false。然后我們在使用 setLoading 狀態(tài)獲取數(shù)據(jù)時將此狀態(tài)設(shè)置為 true。
最后,我們將更新 return 語句以呈現(xiàn)加載狀態(tài)。
return ( {loading ? ( <div classname="Card"> <div classname="header">NAME LIST</div> <searchbar searchfunction="{filterNames}"></searchbar><lists users="{users}"></lists> </div> ) : ( <div classname="loader"></div> )} > );
使用 JavaScript 三元運算符,我們在加載狀態(tài)為 false 時有條件地渲染 SearchBar 和 Lists 組件,然后在加載狀態(tài)為 true 時渲染加載程序。另外,我們創(chuàng)建了一個簡單的加載器來在界面中顯示加載狀態(tài)。
9. 添加一些 CSS 進行樣式設(shè)置
您可以在下面找到特定于此示例的 CSS 文件。
body, html { -webkit-font-smoothing: antialiased; margin: 0; padding: 0; font-family: "Raleway", sans-serif; -webkit-text-size-adjust: 100%; } body { display: flex; justify-content: center; font-size: 1rem/16; margin-top: 50px; } li, ul { list-style: none; margin: 0; padding: 0; } ul { margin-top: 10px; } li { font-size: 0.8rem; margin-bottom: 8px; text-align: center; color: #959595; } li:last-of-type { margin-bottom: 50px; } .Card { font-size: 1.5rem; font-weight: bold; display: flex; flex-direction: column; align-items: center; width: 200px; border-radius: 10px; background-color: white; box-shadow: 0 5px 3px 0 #ebebeb; } .header { position: relative; font-size: 20px; margin: 12px 0; color: #575757; } .header::after { content: ""; position: absolute; left: -50%; bottom: -10px; width: 200%; height: 1px; background-color: #f1f1f1; } .searchBar { text-align: center; margin: 5px 0; border: 1px solid #c4c4c4; height: 20px; color: #575757; border-radius: 3px; } .searchBar:focus { outline-width: 0; } .searchBar::placeholder { color: #dadada; } .loader { border: 15px solid #ccc; border-top: 15px solid #add8e6; border-bottom: 15px solid #add8e6; border-radius: 50%; width: 80px; height: 80px; animation: rotate 2s linear infinite; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
結(jié)論
在本教程中,我們使用隨機用戶生成器 API 作為隨機數(shù)據(jù)源。然后,我們從 API 端點獲取數(shù)據(jù),并使用 map 方法在新的 JavaScript 對象中重構(gòu)結(jié)果。
接下來是使用 filter 和 includes 方法創(chuàng)建過濾函數(shù)。最后,我們創(chuàng)建了兩個不同的組件,并在尚未獲取數(shù)據(jù)時有條件地以加載狀態(tài)渲染我們的組件。
在過去的幾年里,React 越來越受歡迎。事實上,我們在 Envato Market 中有許多項目可供購買、審查、實施等。如果您正在尋找有關(guān) React 的其他資源,請隨時查看它們。