Thứ sáu, 18/09/2020 | 00:00 GMT+7

Cách tạo ứng dụng tìm kiếm ảnh với React bằng API Unsplash

Theo Khảo sát dành cho nhà phát triển StackOverflow 2020 , React là một trong những khung JavaScript phổ biến nhất và có nhiều lý do cho điều này, chẳng hạn như thay đổi hiệu quả các chế độ xem ứng dụng web bằng Virtual DOM , sử dụng các thành phần trạng thái, có thể sử dụng lại, có thể kết hợp để tăng khả năng mở rộng và hơn. Các nhà phát triển React mới bắt đầu thường cần kinh nghiệm để sử dụng kiến thức của họ trong các ứng dụng thực tế. Hướng dẫn này sẽ cung cấp cho bạn trải nghiệm đó bằng cách chỉ cho bạn cách sử dụng React Hooks , sử dụng useState() và thực hiện lệnh gọi API trong React.

Bài viết này sẽ thảo luận về quy trình từng bước xây dựng một ứng dụng tìm kiếm ảnh với React bằng cách sử dụng API Unsplash . Unsplash hiện là một trong những công cụ tìm kiếm ảnh phổ biến và được sử dụng nhiều nhất, đồng thời có thể là một nhà cung cấp dữ liệu tuyệt vời khi xây dựng các dự án và ứng dụng.

Ở cuối hướng dẫn này, bạn sẽ có một ứng dụng đang hoạt động sử dụng React Hooks để truy vấn API Unsplash. Dự án này cũng có thể hoạt động như một bản soạn sẵn, vì bạn có thể sử dụng lại cùng một logic lập trình và có thể sử dụng nó làm cơ sở để xây dựng các dự án khác liên quan đến lệnh gọi API. Ứng dụng tìm kiếm ảnh của bạn sẽ bao gồm một thanh tìm kiếm và các kết quả được hiển thị, như trong hình sau:

Ứng dụng Tìm kiếm Ảnh

Nếu bạn muốn xem mã hoàn chỉnh, hãy xem qua Kho lưu trữ GitHub của Cộng đồng DigitalOcean .

Yêu cầu

Để làm theo hướng dẫn này:

Bước 1 - Tạo một dự án trống

Trong bước này, bạn sẽ sử dụng Create React App , ứng dụng này sẽ chạy dự án ban đầu mà không cần thực hiện bất kỳ cấu hình thủ công nào. Trong folder dự án của bạn, hãy chạy lệnh sau.

  • npx create-react-app react-photo-search

Lệnh này sẽ tạo một folder có tên là react-photo-search với tất cả các file và cấu hình cần thiết cho ứng dụng web React hoạt động.

Sử dụng lệnh cd để thay đổi folder và vào bên trong folder này bằng cách chạy lệnh sau:

  • cd react-photo-search

Tiếp theo, khởi động server phát triển bằng cách chạy lệnh sau:

  • npm start

Để biết thông tin về tập lệnh bắt đầu này, hãy xem Cách cài đặt một dự án React với Tạo ứng dụng React .

Tiếp theo, hãy truy cập http://localhost:3000 trong trình duyệt web hoặc nếu bạn đang chạy nó từ server từ xa, http:// your_domain :3000 .

Bạn sẽ tìm thấy mẫu React:

Mẫu bắt đầu React với logo React

Trước khi di chuyển xa hơn, bạn sẽ phải làm sạch các file . Tạo Ứng dụng React đi kèm với mã mẫu không cần thiết và nên được gỡ bỏ trước khi xây dựng dự án đảm bảo khả năng bảo trì mã.

Đến đây bạn cần phải mở một terminal khác vì một terminal đã được sử dụng trước npm start .

Xóa kiểu mặc định trong index.css bằng cách chạy lệnh sau:

  • rm src/index.css

Tiếp theo, mở index.js trong editor mã bằng lệnh sau:

  • nano src/index.js

Vì bạn đã xóa index.css , hãy xóa import './index.css'; từ index.js .

index.js của bạn sẽ tương tự như vậy sau khi bạn xóa xong import ./index.css khỏi nó.

react-photo-search / src / index.js
 import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import * as serviceWorker from './serviceWorker';  ReactDOM.render(   <React.StrictMode>     <App />   </React.StrictMode>,   document.getElementById('root') );  // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister(); 

Lưu và thoát khỏi file .

Bây giờ xóa logo React bằng cách chạy lệnh sau trong terminal:

  • rm src/logo.svg

Mở App.css bằng lệnh sau:

  • nano src/App.css

Xóa mọi thứ khỏi App.css , sau đó lưu và thoát khỏi file . Bạn sẽ cập nhật điều này ở Bước 3 với kiểu dáng mới của bạn .

Mở src/App.js bằng lệnh sau:

  • nano src/App.js

Bước tiếp theo là xóa import logo from './logo.svg'; và xóa JSX khỏi div với className="App" trong file App.js Thao tác này sẽ xóa các phần tử HTML của mẫu.

Sửa đổi App.js để trông giống như sau:

react-photo-search / src / App.js
import React from 'react'; import './App.css';  function App() {   return (     <div className="App">      </div>   ); }  export default App; 

http://localhost:3000 bạn bây giờ sẽ trống.

Đến đây bạn đã khởi tạo một ứng dụng React và làm sạch mã mẫu khỏi nó. Tiếp theo, bạn sẽ tạo một ứng dụng mới trong console Unsplash Developer và sao chép Access KeySecret Key của ứng dụng bạn vừa tạo để có quyền truy cập vào API Unsplash.

Bước 2 - Nhận thông tin đăng nhập API Unsplash

Trong phần này, bạn sẽ đăng ký Tài khoản nhà phát triển Unsplash, tạo ứng dụng mới cho dự án này và sao chép Access KeySecret Key của ứng dụng này để có quyền truy cập vào API Unsplash. Vì API Unsplash không phải là API công khai, bạn cần bộ khóa API Unsplash của riêng mình cho dự án này.

Đi đến Trang chủ của nhà phát triển Unsplash và đăng ký làm nhà phát triển. Vì bạn đã tạo Tài khoản Unsplash nên đây sẽ là một quá trình nhanh chóng.

Trên trang Unsplash Developer, nhấp vào nút Đăng ký với quyền là nhà phát triển .

Hủy kết nối trang nhà phát triển

Điền vào thông tin đăng ký của bạn để đăng ký.

Sau khi đăng ký làm nhà phát triển, bạn sẽ tự động được chuyển hướng đến trang tổng quan dành cho nhà phát triển của bạn . Nhấp vào Ứng dụng mới .

Hủy kết nối Trang tổng quan dành cho nhà phát triển với ứng dụng mới

Bạn cần chấp nhận Nguyên tắc và sử dụng API . Nhấp vào các hộp kiểm sau đó nhấp vào nút Chấp nhận điều khoản để tiếp tục:

Nguyên tắc và sử dụng API Unsplash

Sau đó, bạn sẽ được yêu cầu cung cấp thông tin Ứng dụng của bạn . Đặt tên và mô tả thích hợp cho ứng dụng của bạn, rồi nhấp vào Tạo ứng dụng .

Bỏ kết nối cửa sổ bật lên thông tin ứng dụng

Với điều này, bạn đã tạo một ứng dụng và hiện có thể truy Access KeySecret Key trong phần Key . Sao chép các khóa này vào một vị trí an toàn; bạn cần chúng sau này trong mã của bạn.

Phần các phím của Trang ứng dụng Unplash

Lưu ý bạn sẽ thấy thẻ Demo sau tên ứng dụng của bạn :

Demottag bên cạnh tên ứng dụng hủy kết nối

Thẻ này nghĩa là ứng dụng của bạn đang ở chế độ phát triển và các yêu cầu được giới hạn ở 50 yêu cầu mỗi giờ. Đối với một dự án cá nhân, điều này là quá đủ, nhưng bạn cũng có thể đăng ký production , điều này sẽ tăng giới hạn yêu cầu lên 5000 mỗi giờ. Hãy nhớ tuân theo Nguyên tắc API trước khi áp dụng.

Trong phần này, bạn đã tạo một ứng dụng API Unsplash và có được các khóa cần thiết cho dự án này. Đối với dự án này, bạn sẽ sử dụng Thư viện JavaScript Unsplash chính thức, unsplash-js , để tích hợp API với ứng dụng của bạn. Bạn sẽ cài đặt unsplash.js và thêm CSS để tạo kiểu cho dự án của bạn trong bước tiếp theo.

Bước 3 - Cài đặt phụ thuộc và thêm CSS

Đến đây bạn sẽ cài đặt gói unsplash-js dưới dạng phụ thuộc và thêm CSS tùy chỉnh để tạo kiểu cho dự án của bạn. Nếu bất kỳ lúc nào bạn gặp khó khăn, hãy tham khảo Kho lưu trữ cộng đồng DigitalOcean cho dự án này .

Để cài đặt thư viện unsplash-js với trình quản lý gói npm , hãy chạy phần sau trong folder dự án của bạn:

  • npm install unsplash-js

Đây là thư viện duy nhất mà bạn cần cài đặt để làm theo hướng dẫn này; về sau, bạn có thể thử nghiệm với các thư viện Giao diện user React khác nhau như React-Bootstrap , Semantic UI React , v.v. Bạn nên thêm các thư viện này nếu sau khi làm theo hướng dẫn này, bạn muốn tinh chỉnh dự án này và thay đổi bố cục của nó.

Tiếp theo, bạn sẽ tạo kiểu cho ứng dụng React của bạn . Mở App.css bằng cách chạy lệnh sau.

  • nano src/App.css

Hướng dẫn này sẽ thảo luận về CSS từng phần.

Đầu tiên là * selector, chọn tất cả các phần tử. Thêm mã sau:

react-photo-search / src / App.css
* {   box-sizing: border-box;   background-color: rgb(244, 244, 244);   color: #333;   font-size: 10px; } 

Thuộc tính box-sizing đặt cách tính tổng chiều rộng và chiều cao của một phần tử và trong trường hợp này, nó yêu cầu trình duyệt đưa đường viền và phần đệm vào tính toán cho chiều rộng và chiều cao của phần tử. Màu nền được đặt bằng cách sử dụng background-color và giá trị là rgb(244, 244, 244) , mang lại màu trắng nhạt cho nền. color cài đặt màu của văn bản của các phần tử; ở đây sử dụng mã hex #333 , có màu xám đậm. font-size đặt kích thước của phông chữ.

Tiếp theo, thêm khối .App , khối này chọn phần tử có className="App" . Theo mặc định, phần tử mẹ ( className="App" ) có một số lề và phần đệm, vì vậy đoạn mã sau đặt margin và phần padding của cả bốn cạnh thành 0 :

react-photo-search / src / App.css
* {   box-sizing: border-box;   background-color: rgb(244, 244, 244);   color: #333;   font-size: 10px; }  .App {   margin: 0;   padding: 0; } 

Tiếp theo, thêm kiểu dáng cho phần tử div với className="container" . Đây là phần tử con của div với className="App" . Mọi thứ bao gồm tiêu đề, biểu mẫu, nút và hình ảnh sẽ có trong div này:

react-photo-search / src / App.css
* {   box-sizing: border-box;   background-color: rgb(244, 244, 244);   color: #333;   font-size: 10px; }  .App {   margin: 0;   padding: 0; }  .container {   margin: 0 auto;   max-width: 1000px;   padding: 40px; } 

Thuộc tính margin được sử dụng để xác định không gian xung quanh các phần tử. margin có thể được đặt cho top , right , bottomleft . Nếu chỉ một giá trị được thêm vào, thì một giá trị này sẽ được đặt cho tất cả top , right , bottomleft . Nếu hai giá trị được thêm vào margin , thì giá trị đầu tiên sẽ được đặt cho topbottom , và giá trị thứ hai sẽ được đặt cho rightleft .

Theo margin: 0 auto; , topbottom0 lề trong khi leftrightauto . Tự auto này nghĩa là trình duyệt sẽ đặt lề dựa trên containers . Một ví dụ để hiểu điều này sẽ là nếu phần tử mẹ là 100px và phần tử con là 50px , thì lề leftright sẽ là 25px , sẽ căn giữa phần tử con bên trong phần tử mẹ.

max-width đặt giá trị width lớn nhất của phần tử, trong trường hợp này là 1000px . Nếu nội dung lớn hơn 1000px , thì thuộc tính height của phần tử sẽ thay đổi tương ứng, còn lại max-width sẽ không có hiệu lực.

Như đã thảo luận ở trên, margin đặt khoảng trống xung quanh phần tử trong khi padding đặt khoảng cách giữa phần tử và nội dung của nó. Đoạn mã trước đó nghĩa là div container và các phần tử bên trong nó sẽ có 40px không gian giữa chúng từ cả bốn phía.

Tiếp theo, thêm kiểu cho tiêu đề của ứng dụng:

react-photo-search / src / App.css
... .container {   margin: 0 auto;   max-width: 1000px;   padding: 40px; }  .title {   font-size: 4.4rem;   font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; } 

.title tương ứng với tiêu đề Ứng dụng của bạn, đó là “Tìm kiếm ảnh phản ứng”. Chỉ có hai thuộc tính được cài đặt , đó là font-sizefont-family . Ở đây, đơn vị rem được sử dụng cho giá trị font-size . rem giá trị rem có liên quan đến phần tử html root , không giống như các giá trị em , có liên quan đến phần tử mẹ. Ở đây 4.4rem nghĩa là 44px (4.4 x 10). Phép nhân với 10px này là do bạn đặt kích thước phông chữ của tất cả các phần tử thành 10px bằng cách sử dụng * selector. font-family chỉ định phông chữ của phần tử. Có nhiều giá trị được truyền vào mã để hoạt động như một hệ thống dự phòng ; nếu trình duyệt không cung cấp phông chữ đầu tiên, phông chữ tiếp theo sẽ được đặt.

Tiếp theo là khối CSS .form , bao gồm biểu mẫu sẽ được sử dụng để tìm kiếm hình ảnh. Điều này bao gồm trường tìm kiếm đầu vào, nút và nhãn.

react-photo-search / src / App.css
... .title {   font-size: 4.4rem;   font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; }  .form {   display: grid; } 

Ở đây, chỉ thuộc tính display được cài đặt . Thuộc tính này chỉ định hành vi hiển thị của phần tử. Nó có thể nhận các giá trị khác nhau như grid , flex , block , inline , v.v. grid hiển thị một phần tử ở mức khối và hiển thị nội dung theo mô hình lưới .

Tiếp theo là .label và khối CSS .input :

react-photo-search / src / App.css
... .form {   display: grid; }  .label {   font-size: 3rem;   margin-bottom: 1rem; }  .input {   font-size: 1.6rem;   padding: 0.5rem 2rem;   line-height: 2.8rem;   border-radius: 20px;   background-color: white;   margin-bottom: 1rem; } 

Ta đã thảo luận về font-size , phần padding , background-colormargin-bottom , vì vậy hãy thảo luận về line-heightborder-radius . border-radius xác định bán kính của các góc của phần tử. Ở đây giá trị được đặt thành 20px , sẽ được sử dụng cho cả bốn cạnh. Đặt border-radius thành 50% có thể biến một phần tử hình vuông thành hình bầu dục. line-height chỉ định chiều cao của dòng, được đặt thành 2.8rem hoặc 28px .

Tiếp theo là khối CSS .button , tạo kiểu cho nút Tìm kiếm :

react-photo-search / src / App.css
... .input {   font-size: 1.6rem;   padding: 0.5rem 2rem;   line-height: 2.8rem;   border-radius: 20px;   background-color: white;   margin-bottom: 1rem; }  .button {   background-color: rgba(0, 0, 0, 0.75);   color: white;   padding: 1rem 2rem;   border: 1px solid rgba(0, 0, 0, 0.75);   border-radius: 20px;   font-size: 1.4rem;   cursor: pointer;   transition: background-color 250ms; } 

Ta đã thảo luận về background-color , color , padding , border-radiusfont-size . border đặt kiểu, chiều rộng và màu sắc của đường viền của một phần tử. Ở đây, border được sử dụng làm thuộc tính viết tắt cho border-width border-style border-color . Mã này thêm một đường viền màu đen đặc có kích thước 1px xung quanh nút Tìm kiếm . cursor chỉ định con trỏ chuột khi trỏ chuột qua một phần tử.

Tiếp theo là :hover bộ chọn :hover , được sử dụng trên .button .

react-photo-search / src / App.css
... .button {   background-color: rgba(0, 0, 0, 0.75);   color: white;   padding: 1rem 2rem;   border: 1px solid rgba(0, 0, 0, 0.75);   border-radius: 20px;   font-size: 1.4rem;   cursor: pointer;   transition: background-color 250ms; }  .button:hover {   background-color: rgba(0, 0, 0, 0.85); } 

Điều này nghĩa là khi di chuột qua phần tử .button , màu nền sẽ thay đổi.

Khối CSS tiếp theo là .card-list , tương ứng với div với className="card-list" . div này sẽ hiển thị tất cả các hình ảnh bên trong nó:

react-photo-search / src / App.css
... .button:hover {   background-color: rgba(0, 0, 0, 0.85); }  .card-list {   column-count: 3; } 

column-count chia phần tử thành các cột theo giá trị được chuyển vào bên trong nó. Mã này sẽ chia div card-list thành ba cột và hình ảnh sẽ được hiển thị trong ba cột này.

Tiếp theo là các khối CSS .card.card--image . .card đề cập đến div riêng lẻ với một hình ảnh bên trong nó và .card--imageclassName của hình ảnh này:

react-photo-search / src / App.css
... .card-list {   column-count: 3; }  .card {     margin-bottom: 1rem;     display: flex; }  .card--image {     flex: 100%;     margin-top: 1rem;     border-radius: 10px; } 

Ta đã thảo luận về margin , displayborder-radius . Trong .card , display được đặt thành flex , nghĩa là các phần tử sẽ hoạt động giống như các phần tử khối và hiển thị sẽ được đặt theo mô hình flexbox . Bằng cách sử dụng thuộc tính viết tắt flex:100%; , bạn đặt giá trị cho flex-grow , flex-shrinkflex-basis . Bạn có thể đọc thêm về nó tại Mạng nhà phát triển Mozilla .

Các khối CSS cuối cùng liên quan đến các media query . Bằng cách sử dụng luật @media , bạn có thể áp dụng các kiểu khác nhau cho các loại / thiết bị phương tiện khác nhau:

react-photo-search / src / App.css
... .card--image {     flex: 100%;     margin-top: 1rem;     border-radius: 10px; }  @media (min-width: 768px) {   .form {     grid-template-columns: auto 1fr auto;     grid-gap: 1rem;     align-items: center;   }   .input {     margin-bottom: 0;   } }  @media only screen and (max-width: 600px) {     .card-list {         column-count: 1;     } } 

Theo mã này, column-count sẽ thay đổi từ 3 thành 1 khi cửa sổ trình duyệt có kích 600px trở xuống (áp dụng cho hầu hết các thiết bị di động). Điều này đã sử dụng thuộc tính max-width với luật @media . Mã trước đó sử dụng min-width , thay đổi kiểu của các phần tử bên trong luật @media khi chiều rộng từ 768px trở lên.

grid-template-columns được sử dụng để chỉ định các cột trong mô hình lưới. Số cột bằng với số giá trị được truyền, là ba theo mã ( auto 1fr auto ). Kích thước của phần tử lưới thứ nhất và thứ ba sẽ theo kích thước containers của chúng hoặc kích thước của nội dung. Phần tử thứ hai sẽ có 1fr (Đơn vị phân số), hoặc khoảng trống còn lại sau khi phần tử thứ nhất và thứ ba đã chiếm dụng theo kích thước của chúng. Ba yếu tố này sẽ là biểu tượng cảm xúc máy ảnh, trường nhập tìm kiếm và nút Tìm kiếm . Sau khi biểu tượng cảm xúc và nút đã chiếm không gian theo kích thước của chúng, phần còn lại của khu vực sẽ chuyển đến trường nhập tìm kiếm và nó sẽ thay đổi chiều rộng tương ứng.

grid-gap: 1rem; tạo không gian 1rem giữa hai lưới ô 1rem . align-items:center; đặt các mục ở trung tâm của container .

Điều này hoàn thành việc tạo kiểu ứng dụng của bạn. Lưu và thoát khỏi src/App.css . Nếu bạn muốn xem toàn bộ file CSS cùng nhau, hãy xem kho lưu trữ GitHub để biết mã này .

Đến đây bạn đã cài đặt phần phụ thuộc cần thiết và thêm CSS tùy chỉnh cần thiết để tạo kiểu cho dự án của bạn , bạn có thể chuyển sang phần tiếp theo và thiết kế giao diện user hoặc bố cục của dự án.

Bước 4 - Thiết kế giao diện user

Trong phần này, bạn sẽ thiết kế giao diện user của dự án. Điều này sẽ bao gồm các phần tử như tiêu đề, nhãn, trường đầu vào và nút.

Mở file src/App.js bằng lệnh sau:

  • nano src/App.js

Để thêm một tiêu đề vào dự án của bạn, hãy tạo một div với className="container" bên trong App.js của bạn. Bên trong div này thêm một thẻ h1 với className="title" và viết React Photo Search bên trong thẻ. Đây sẽ là tiêu đề tiêu đề:

react-photo-search / src / App.js
import React from 'react'; import './App.css';  function App() {   return (     <div className="App">       <div className="container">         <h1 className="title">React Photo Search</h1>       </div>     </div>   ); } 

Lưu và thoát khỏi file . Trong trình duyệt của bạn, ứng dụng của bạn bây giờ sẽ hiển thị tiêu đề của bạn:

Ứng dụng có tiêu đề "React Photo Search"

Tiếp theo, bạn sẽ tạo một biểu mẫu sẽ lấy đầu vào từ user . Biểu mẫu này sẽ bao gồm một trường văn bản đầu vào và một nút gửi.

Đối với điều này, hãy tạo mộtthành phần mới có tên <SearchPhotos /> . Không nhất thiết phải tạo một thành phần riêng biệt, nhưng khi bạn phát triển dự án này, việc chia nhỏ mã thành các thành phần sẽ giúp viết và duy trì mã dễ dàng hơn.

Trong folder src , tạo và mở một file mới có tên là searchPhotos.js bằng lệnh sau:

  • nano src/searchPhotos.js

Bên trong searchPhotos.js , bạn xuất một thành phần chức năng có tên <SearchPhotos /> :

react-photo-search / src / searchPhotos.js
import React from "react";  export default function SearchPhotos() {   return (     <>      </>   ); } 

Đây là cấu trúc cơ bản của một thành phần chức năng mà bạn cần thêm vào file searchPhotos.js . Lưu file này.

Bước tiếp theo là để nhập khẩu và sử dụng SearchPhotos thành phần trong App.js .

Trong cửa sổ terminal mới, hãy mở App.js :

  • nano src/App.js

Thêm các dòng được đánh dấu sau vào App.js :

react-photo-search / src / App.js
import React from "react"; import "./App.css"; import SearchPhotos from "./searchPhotos"  function App() {   return (     <div className="App">       <div className="container">         <h1 className="title">React Photo Search</h1>         <SearchPhotos />        </div>     </div>   ); } export default App; 

Lưu file này.

Để tạo biểu mẫu tìm kiếm, bạn sẽ sử dụng thẻ form và bên trong nó, tạo trường nhập liệu bằng thẻ input và một nút bằng thẻ button .

Cung cấp cho các phần tử tên className của các thẻ tương ứng của chúng. Trong khi bạn đang làm điều này, hãy thêm nhãn có biểu tượng cảm xúc máy ảnh bên trong để tạo kiểu:

react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() {   return (     <>       <form className="form">          <label className="label" htmlFor="query">            {" "}           📷         </label>         <input           type="text"           name="query"           className="input"           placeholder={`Try "dog" or "apple"`}         />         <button type="submit" className="button">           Search         </button>       </form>     </>   ); } 

Đầu tiên, bạn đã tạo một phần tử form với className="form" và bên trong nó là một label có biểu tượng cảm xúc máy ảnh. Sau đó, đến phần tử input với các thuộc tính type="text" , vì truy vấn tìm kiếm sẽ là một chuỗi . Thuộc tính name="query" chỉ định tên của phần tử input , className="input" cung cấp cho phần tử một lớp để tạo kiểu và giá trị giữ chỗ cho thanh tìm kiếm được đặt thành Try "dog" or "apple" . Phần tử cuối cùng trong form là một buttontype="submit" .

Lưu và thoát khỏi file . Ứng dụng của bạn bây giờ sẽ có một thanh tìm kiếm sau tiêu đề:

Ứng dụng có thanh tìm kiếm và văn bản giữ chỗ của 'Hãy thử "dog" hoặc "apple"'

Bây giờ giao diện user của ứng dụng đã hoàn tất, bạn có thể bắt đầu làm việc trên các chức năng bằng cách lưu trữ truy vấn đầu vào từ user trong phần tiếp theo.

Bước 5 - Đặt trạng thái bằng cách sử dụng truy vấn tìm kiếm

Trong bước này, bạn sẽ tìm hiểu về các trạng tháiReact Hooks và sau đó sử dụng chúng để lưu trữ thông tin đầu vào của user .

Đến đây bạn đã xây dựng cấu trúc cơ bản cho ứng dụng của bạn , ta có thể thảo luận về khía cạnh React của mọi thứ. Bạn có một biểu mẫu, nhưng nó chưa làm được gì, vì vậy việc đầu tiên cần làm là lấy đầu vào từ thanh tìm kiếm và truy cập vào nó. Bạn có thể làm điều này với các trạng thái.

Phần cốt lõi của chúng là các đối tượng được sử dụng để lưu trữ các giá trị thuộc tính của các thành phần. Mỗi khi trạng thái thay đổi, thành phần sẽ hiển thị lại. Đối với ứng dụng này, bạn cần một trạng thái sẽ lưu trữ dữ liệu nhập hoặc truy vấn từ thanh tìm kiếm khi nào nút Tìm kiếm được nhấp.

Một trong những điều mà bạn có thể nhận thấy là dự án này đang sử dụng các thành phần chức năng. Điều này cho phép bạn sử dụng React Hooks để quản lý trạng thái. Hook là các hàm sử dụng các tính năng của React như xác định trạng thái mà không cần viết một lớp. Trong hướng dẫn này, bạn sẽ sử dụng useState() .

Điều đầu tiên cần làm là nhập useState bên trong file searchPhotos.js của bạn.

Mở file :

  • nano src/searchPhotos.js

Sửa đổi dòng đầu tiên của file searchPhotos.js thành dòng sau:

react-photo-search / src / searchPhotos.js
import React, { useState } from "react";  export default function SearchPhotos() { ... 

Tiếp theo, bạn sẽ triển khai useState() . Đây là cú pháp cho useState() Hook:

useState(initialState) 

useState() trả về trạng thái hiện tại và một hàm thường được gọi là hàm cập nhật. Để lưu trữ những thứ này, bạn có thể sử dụng cấu trúc hủy mảng :

const [query, setQuery] = useState(initialState); 

Trong ví dụ này, query lưu trữ trạng thái hiện tại của thành phần và setQuery là một hàm có thể được gọi để cập nhật trạng thái. initialState xác định giá trị trạng thái ban đầu; nó có thể là một chuỗi, một số, một mảng hoặc một đối tượng tùy theo mục đích sử dụng.

Trong dự án của bạn, đầu vào từ thanh tìm kiếm là một chuỗi, vì vậy bạn sẽ sử dụng một chuỗi rỗng làm giá trị ban đầu của trạng thái.

Trong file searchPhotos.js của bạn, hãy thêm dòng mã sau:

react-photo-search / src / searchPhotos.js
...  export default function SearchPhotos() {   const [query, setQuery] = useState("");    return (     <>       <form className="form">         <label className="label" htmlFor="query">           {" "}           📷         </label> ... 

Bước tiếp theo là đặt value của trường văn bản đầu vào để query và thêm sự kiện onChange() vào đó. Sự kiện onChange() này sẽ có một hàm, bên trong hàm setQuery() sẽ được sử dụng để cập nhật trạng thái. Chuỗi đầu vào được truy xuất bằng e.target.value :

react-photo-search / src / searchPhotos.js
... <input     type="text"     name="query"     className="input"     placeholder={`Try "dog" or "apple"`}     value={query}     onChange={(e) => setQuery(e.target.value)} /> ... 

Bây giờ, trạng thái và giá trị của trường đầu vào được liên kết với nhau và bạn có thể sử dụng truy vấn tìm kiếm này để tìm kiếm hình ảnh.

Bạn có thể xem đầu vào từ thanh tìm kiếm bên trong query trong thời gian thực cho mục đích thử nghiệm. Thêm console.log(query) ngay sau nơi bạn đã xác định trạng thái:

react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() {    const [query, setQuery] = useState("");    console.log(query);    return (     <>     //     </>   ); } 

Lưu các file .

Đến đây bạn sẽ nhận được các truy vấn đầu vào bên trong console . Bạn có thể mở console của bạn bằng cách sử dụng F12 trong Chrome hoặc Ctrl+Shift+K trong Firefox :

 Control panel  trình duyệt thể hiện việc ghi log  đầu vào của  user  cho ứng dụng này.

Bây giờ, searchPhotos.js sẽ giống như sau:

react-photo-search / src / searchPhotos.js
 import React, { useState } from "react"; export default function SearchPhotos() {   const [query, setQuery] = useState("");   console.log(query);    return (     <>       <form className="form">         <label className="label" htmlFor="query">           {" "}           📷         </label>         <input           type="text"           name="query"           className="input"           placeholder={`Try "dog" or "apple"`}           value={query}           onChange={(e) => setQuery(e.target.value)}         />         <button type="submit" className="button">           Search         </button>       </form>     </>   ); } 

Phần này thảo luận về các trạng thái và React Hooks và lưu trữ đầu vào của user trong trường input bên trong trạng thái query . Trong phần tiếp theo, bạn sẽ sử dụng truy vấn tìm kiếm này để tìm kiếm hình ảnh và lưu trữ phản hồi bên trong một trạng thái khác.

Bước 6 - Đưa ra yêu cầu API để hủy kết nối

Đến đây bạn sẽ sử dụng thư viện unsplash-js để tìm kiếm hình ảnh bằng cách sử dụng truy vấn từ trường input . Phản hồi sẽ được lưu trữ bên trong một trạng thái khác có tên là pics .

Bạn đã cài đặt thư viện unsplash-js , vì vậy hãy nhập nó vào file searchPhotos.js . Bạn cũng có thể xóa câu lệnh console.log() khỏi phần trước:

react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; import Unsplash, { toJson } from "unsplash-js";  ... 

toJson là một hàm trợ giúp trong thư viện unsplash-js được sử dụng để chuyển đổi phản hồi thành định dạng JSON . Bạn có thể tìm hiểu thêm về các chức năng trợ giúp tại trang GitHub unsplash-js .

Để sử dụng Unsplash trong ứng dụng của bạn, hãy tạo một version của nó bằng cách sử dụng từ khóa new như sau:

react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; import Unsplash, { toJson } from "unsplash-js";  const unsplash = new Unsplash({   accessKey: "your_Access_Key", }); 

Dán Khóa Access Key Unsplash của bạn để thay thế your_Access_Key và bây giờ bạn có thể thực hiện các yêu cầu API.

Cảnh báo: Người ta không bao giờ nên chia sẻ bất kỳ khóa truy cập hoặc ID ứng dụng nào cho API hoặc bất kỳ dịch vụ nào. Những kẻ xấu tiềm ẩn có thể lạm dụng chúng qua internet. Trong trường hợp này, họ có thể đưa ra một lượng yêu cầu bất thường có thể bị nhà cung cấp dịch vụ của bạn gắn cờ là spam, có thể hủy kích hoạt ứng dụng và account của bạn.

Đến đây bạn sẽ tạo một hàm không đồng bộ sẽ được kích hoạt khi nhấp vào nút Tìm kiếm .

Ngay sau khi nơi bạn định nghĩa nhà nước để query , xác định một async chức năng:

react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() {   const [query, setQuery] = useState("");    const searchPhotos = async (e) => {     e.preventDefault();     console.log("Submitting the Form")   }; 

Tại đây e.preventDefault() ngừng reload trang khi nào nhấp vào nút Tìm kiếm . Bạn có thể chuyển hàm này trong sự kiện onSubmit bên trong thẻ form . Bạn có thể đọc thêm về điều này trong tài liệu chính thức của React .

react-photo-search / src / searchPhotos.js
...   return (     <>       <form className="form" onSubmit={searchPhotos}> ... 

Lưu các file . Bây giờ, nếu bạn nhấp vào nút Tìm kiếm , bạn sẽ nhận được Submitting the Form trong console . Bạn có thể xóa console.log() sau khi phản hồi thành công trong console .

Bên trong hàm searchPhotos() bạn, bạn sẽ sử dụng thể hiện Unsplash ( unsplash ). Bạn có thể sử dụng search phương pháp để tìm kiếm các hình ảnh. Đây là cú pháp cho điều đó:

search.photos(keyword, page, per_page, filters) 

Đây là mã để tìm kiếm hình ảnh; thêm mã này vào bên trong hàm searchPhotos() của bạn:

react-photo-search / src / searchPhotos.js
... const searchPhotos = async (e) => {   e.preventDefault();   unsplash.search     .photos(query)     .then(toJson)     .then((json) => {       console.log(json);     }); }; ... 

Đầu tiên, bạn sử dụng unsplash.search và sau đó chỉ định những gì cần tìm kiếm, trong trường hợp này là photos . Ta cũng có thể tìm kiếm users hoặc collections . photos lấy đối số bắt buộc đầu tiên làm từ khóa để tìm kiếm, đó là query ; bạn cũng có thể chỉ định trang, phản hồi trên mỗi trang, hướng hình ảnh, v.v., thông qua các đối số tùy chọn. Đối với hướng dẫn này, bạn chỉ cần các đối số pageper_page , giới hạn các mục phản hồi bạn nhận được từ Unsplash.

Đây là tất cả các đối số có thể được cung cấp trong photos

Tranh luận Kiểu Chọn / Bắt buộc Mặc định
keyword chuỗi Cần thiết
page con số Không bắt buộc
per_page con số Không bắt buộc 10
filters vật Không bắt buộc
filters.orientation chuỗi Không bắt buộc
filters.collections mảng Không bắt buộc

Bạn có thể tìm hiểu thêm về chúng tại trang GitHub unsplash-js .

Bạn sử dụng phương thức toJson để chuyển đổi phản hồi thành JSON và cuối cùng, console.log() phản hồi để kiểm tra xem các yêu cầu API được thực hiện mà không có bất kỳ lỗi nào. Bạn sẽ xóa bảng console .log () này console .log () trong các bước tiếp theo.

Lưu các file . Bây giờ, hãy mở console của bạn và nhấp vào nút Tìm kiếm . Bạn sẽ tìm thấy một JSON phản hồi như sau:

{   "results": [{      "description": "Pink Wall Full of Dogs",      "alt_description": "litter of dogs fall in line beside wall",      "urls": {            "raw": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjE0MTQxN30",            "full": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0MTQxN30",            "regular": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30",            "small": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30",            "thumb": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30"                 },     ... } 

Bạn có thể xóa hoặc comment câu lệnh console.log() khi bạn tìm thấy phản hồi thành công từ API Unsplash, nghĩa là mã của bạn đang hoạt động tốt. Ứng dụng này sẽ sử dụng trường "urls" , vì đó sẽ là nguồn của hình ảnh.

Đến đây bạn đã sử dụng truy vấn từ user để tìm kiếm hình ảnh khi nút Tìm kiếm được nhấp bằng cách sử dụng thư viện unsplash-js . Tiếp theo, bạn sẽ lưu trữ phản hồi bên trong một trạng thái khác có tên là các pics và hiển thị các hình ảnh bằng cách ánh xạ các phần tử bên trong trạng thái này.

Bước 7 - Hiển thị hình ảnh trên trang web

Trong phần cuối cùng này, bạn sẽ lưu trữ phản hồi từ Unsplash API bên trong một trạng thái khác có tên là các pics và sau đó ánh xạ các phần tử của trạng thái này để hiển thị hình ảnh trên trang web.

Để hiển thị hình ảnh, bạn cần truy cập vào JSON phản hồi và đối với điều đó, cần một trạng thái khác. query trạng thái trước đó đã lưu trữ các truy vấn từ user , được sử dụng để thực hiện các yêu cầu đối với API Unsplash. Các pics trạng thái này sẽ lưu trữ phản hồi hình ảnh mà bạn nhận được từ API Unsplash.

Trong searchPhotos.js xác định một trạng thái khác như sau:

react-photo-search / src / searchPhotos.js
...   const [query, setQuery] = useState("");   const [pics, setPics] = useState([]); ... 

Trạng thái này đã được khởi tạo với một mảng trống và tất cả các phản hồi sẽ được lưu trữ dưới dạng một đối tượng bên trong trạng thái này. Nói cách khác, đây là một mảng các đối tượng.

Để cập nhật trạng thái này với JSON, bạn sẽ sử dụng setPics bên trong yêu cầu API unsplash :

react-photo-search / src / searchPhotos.js
...     unsplash.search       .photos(query, 1, 20)       .then(toJson)       .then((json) => {         setPics(json.results);   }); ... 

Bây giờ mỗi khi bạn tìm kiếm một truy vấn mới, trạng thái này sẽ được cập nhật tương ứng.

Tiếp theo, tạo một div với className="card-list" ngay sau nơi thẻ form kết thúc:

react-photo-search / src / searchPhotos.js
...         <button type="submit" className="button">           Search         </button>       </form>       <div className="card-list">       </div>     </>   ); } 

Bên trong div này, bạn sẽ ánh xạ qua trạng thái và hiển thị id của hình ảnh:

react-photo-search / src / searchPhotos.js
...         <button type="submit" className="button">           Search         </button>       </form>       <div className="card-list">         {pics.map((pic) => pic.id )}       </div>     </>   ); } 

Trước tiên, bạn sử dụng {} để chuyển biểu thức JavaScript, bên trong đó bạn sử dụng phương thức .map() cho trạng thái của bạn .

Lưu file của bạn. Nếu bạn tìm kiếm ngay bây giờ, bạn sẽ thấy id được liên kết với các đối tượng khác nhau trên trang web:

Ứng dụng có kết quả ID chồng chéo được hiển thị trên trang web

Điều này thật lộn xộn, nhưng điều này cũng nghĩa là ứng dụng của bạn đang hoạt động.

Thay vì hiển thị pic.id , hãy mở JSX bên trong hàm map và tạo một div mới với className="card" . Đây sẽ là containers cho từng hình ảnh riêng lẻ:

react-photo-search / src / searchPhotos.js
...         <button type="submit" className="button">           Search         </button>       </form>       <div className="card-list">         {           pics.map((pic) => <div className="card"></div>);         }       </div>     </>   ); } 

Đến đây bạn có thể hiển thị một hình ảnh bên trong div này:

react-photo-search / src / searchPhotos.js
...         <button type="submit" className="button">           Search         </button>       </form>       <div className="card-list">         {           pics.map((pic) =>              <div className="card">               <img                 className="card--image"                 alt={pic.alt_description}                 src={pic.urls.full}                 width="50%"                 height="50%"               ></img>             </div>);         }       </div>     </>   ); } 

Nếu bạn quay lại và xem JSON phản hồi, bạn sẽ tìm thấy một loại thông tin khác. "urls" chứa đường dẫn đến hình ảnh, vì vậy ở đây pic.urls.full là đường dẫn thực tế đến hình ảnh và pic.alt_description là mô tả thay thế của hình ảnh.

Có các trường khác nhau bên trong "urls" cung cấp dữ liệu khác nhau, chẳng hạn như:

raw : Hình ảnh thô thực tế do user chụp.
full : Ảnh thô ở định dạng .jpg .
regular : Tốt nhất cho các mục đích sử dụng thực tế, width=1080px .
small : Hoàn hảo cho tốc độ internet chậm, width=400px .
thumb : Phiên bản hình thu nhỏ của hình ảnh, width=200px .

Trong hướng dẫn này, bạn đang sử dụng full , nhưng bạn cũng có thể thử nghiệm với các loại khác. Bạn cũng đã cung cấp heightwidth mặc định cho hình ảnh.

Lưu file của bạn.

Ứng dụng của bạn gần như đã hoàn thành; nếu bạn tìm kiếm ngay bây giờ, bạn có thể thấy ứng dụng của bạn đang hoạt động. Nhưng vẫn còn một dòng mã nhỏ. Nếu bạn tìm kiếm hình ảnh của bạn và truy cập console trong trình duyệt, bạn sẽ thấy một cảnh báo.

Web console
Warning: Each child in a list should have a unique "key" prop.

Để khắc phục điều này, hãy chuyển một key duy nhất cho mọi trẻ em bằng cách sử dụng id của hình ảnh. key prop này cho React biết rõ ràng danh tính của từng đứa trẻ trong danh sách; điều này cũng ngăn trẻ em mất trạng thái giữa các lần hiển thị:

react-photo-search / src / searchPhotos.js
...       <div className="card-list">         {pics.map((pic) =>           <div className="card" key={pic.id}>             <img               className="card--image"               alt={pic.alt_description}               src={pic.urls.full}               width="50%"               height="50%"             ></img>           </div>)};       </div>     </>   ); } 

Bạn có thể điều chỉnh số lượng hình ảnh bạn muốn hiển thị bằng cách chuyển đối số tương ứng đến unsplash.search.photos() .

Lưu và thoát khỏi file . Đến đây bạn sẽ có một ứng dụng tìm kiếm ảnh đang hoạt động:

Hoạt ảnh tìm kiếm cụm từ "quả táo" trong ứng dụng và nhận kết quả hình ảnh quả táo

Trong phần này, bạn đã lưu trữ phản hồi từ API Unsplash bên trong trạng thái pics và hiển thị hình ảnh bằng cách ánh xạ qua các phần tử trong pics .

Kết luận

Trong hướng dẫn này, bạn đã phát triển ứng dụng React Photo Search với API Unsplash. Khi xây dựng dự án, hướng dẫn đã thảo luận về cách sử dụng React Hooks, truy vấn API và tạo kiểu giao diện user .

Có rất nhiều điều có thể làm với ứng dụng này để mở rộng nó. Ví dụ: bạn có thể thêm nút Ngẫu nhiên để hiển thị hình ảnh ngẫu nhiên, tạo hộp kiểm để chuyển đổi giữa tìm kiếm ảnh hoặc user đã đăng chúng theo sở thích của user , thêm cuộn vô hạn để hiển thị nhiều hình ảnh hơn, v.v. Bạn cũng có thể sử dụng khái niệm tương tự và thực hiện các dự án khác liên quan đến các yêu cầu API, chẳng hạn như API Tin tức của Hacker .

Nếu bạn muốn xem thêm các hướng dẫn về React, hãy xem trang Chủ đề React của ta .


Tags:

Các tin trước