Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/william-zhan-bot/react_photo_website
以前用React寫相片的網站,主要集中在api的調用以及用route的練習
https://github.com/william-zhan-bot/react_photo_website
css frontend html javascript pexels pexels-api react reactjs
Last synced: about 11 hours ago
JSON representation
以前用React寫相片的網站,主要集中在api的調用以及用route的練習
- Host: GitHub
- URL: https://github.com/william-zhan-bot/react_photo_website
- Owner: William-Zhan-bot
- Created: 2024-08-29T16:04:58.000Z (29 days ago)
- Default Branch: main
- Last Pushed: 2024-08-29T16:09:55.000Z (29 days ago)
- Last Synced: 2024-09-27T14:41:25.185Z (about 11 hours ago)
- Topics: css, frontend, html, javascript, pexels, pexels-api, react, reactjs
- Language: JavaScript
- Homepage:
- Size: 346 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React_photo_website
製作以React為基底的相片網站 from Udemy Courses 2022網頁全端開發
以下為之前學習的筆記技術總結:
1. React模式製作
2. Routing in React
3. css + google fonts
4. Fetch API
5. 更多圖片5.2.3版 Route examples
```jsx
import About from "./pages/About";
import { Switch, Route } from "react-router-dom";
function App() {
return (
// exact 代表要完全符合 path 的值, 才會顯示
);
}
```6.0.2 版Route examples
```jsx
import About from "./pages/About";
import { Routes, Route } from "react-router-dom";
function App() {
return (
} />
} />
);
}
```## Router in React
套件
```jsx
npm install react-router-dom
```index設定Routes
```jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
// routes設定在這裡
import { BrowserRouter } from "react-router-dom";// BrowserRouter => 包住tag 指定Router
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
);
```in Apps.jsx
```jsx
// 導入各個頁面
import React from "react";
import Nav from "./components/Nav";
import Footer from "./components/Footer";
import Homepage from "./pages/Homepage";
import About from "./pages/About";// Route Set
/**導入routes節點切換器以及route設定節點
* 把節點放進去裡面
* 新版本不會有route需要輸入exact的問題產生
*
* 另外就是要跟Nav後面的 href配合
* 導入React當中的link to去實作
*/
import { Routes, Route } from "react-router-dom";
function App() {
return (
} />
} />
);
}export default App;
```Nav.jsx
```jsx
import React from "react";
// React router dom裡面希望用link
import { Link } from "react-router-dom";const Nav = () => {
return (
Homepage
About
);
};export default Nav;
```## CSS + Google fonts
**css技巧**
在App.jsx導入唯一的css檔
```jsx
*import* styles *from* "./styles/style.css";
```之後後面從sass把各支sass串起來即可
前面加斜線是方便導入可以接上
```jsx
// 直接這行串接css 導入一次即可
// 必須用這樣的引入才可以連接libs
@import "./nav";
@import "./search";
@import "./footer";
```![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/432b441e-ecff-48c6-9b4e-027cb0d41894/Untitled.png)
**設定footer壓底**
在Pages當中,利用inline的css設定頁面長度,把footer壓到底下
```jsx
```**Google font複習**
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/cdc6459c-f4a0-410b-a54e-28aa5c64b48e/Untitled.png)
字體會有link跟css
css丟掉sass裡面的font-family進行設定
link要丟到預設的Header
也就是public中的index.html
!!注意!!是.html裡面
即可導入該字體使用
## Fetch API + 更多圖片
精選相片
先參考pexels的api,裡面影一個自動的推薦15張
搜尋相片
連接pexel的api去查找
**api fetch問題**
每次進入頁面讓他載入照片,採用useEffect去製作即可。
**搜尋問題**
關於方格的抓取,有用一個inputHandler以onChange去及時記錄搜尋欄state的變化,之後已``的方式連接url即可。
**更多照片問題**
必須新增一個state為page並放入url,讓每次按下的more會回傳出不同的東西,之後以concact的方式根原本處理過的photo array相連,即可做到array連貫的部分。
不須擔心data為空報錯,因為會是一開始載入過後,useEffect頁面更新後的data = [data.photos](http://data.photos)陣列,不會是空的arr。
關於搜尋部分的state改變,因為採用即時抓取,可能因此會產生按下more,但自己執行了輸入框條件的問題(因為採即時更新state,不為空即被視為有搜尋條件)。所以必須多創造一個currentSearch,並放在search按鈕當中做state的改變,但卻不會因此改到真正的URL,因為再函式內改過的state會根據js的scope原則,只能在函式當中進行調用,若是運算的話會發生錯誤。
**scope examples:**
```jsx
const i = 5;function test(){
i += 3; // 無法使用
console.log(i); // 無法使用
}
test();
```所以必須以全域的方式去讓他改變,也就是回到global的scope去做操作。
方法為用useEffect,跟上面一開始的search融合,利用對input條件的判斷(剛載入時input必為空),去調整search對應的網址,即可解決此問題,同時也結合前面currentSearch的state,解決了無輸入更新的問題。
```jsx
useEffect(() => {
if (input === "") {
search(initialURL);
} else {
search(searchURL);
}
}, [currentSearch]);
```Homepage.jsx
```jsx
import React from "react";
import Search from "../components/Search";
// 導入state配合Search
import { useState, useEffect } from "react";
import Photo from "../components/Photo";const Homepage = () => {
// 頁面刷新,主要處理api中page的部分
const [page, setPage] = useState(1);
// 處理state小bug =>不按下搜尋也出現相關資訊
// 把所有的input改成這個 多一層檢驗
// 之丟到search按鈕的click裡面去
const [currentSearch, setcurrentSearch] = useState("");// 搜尋列專用
const [input, setInput] = useState("");
const searchURL = `https://api.pexels.com/v1/search?query=${currentSearch}&per_page=15&page=${page}`;// 設定存放資料的state
let [data, setData] = useState(null);
const auth = "563492ad6f91700001000001f5a17c93ac8d4005b0bc658071d73eac";
const initialURL = "https://api.pexels.com/v1/curated?page=1&per_page=15";// 設定從api撈data
const search = async (url) => {
// 預設state是1 => 會先用他拿載入的data
// 之後頁面載入的話會從2開始往後+
// 這樣就不會重複
setPage(2);// api連接
// 裡面的headers是依照參考的部分
const dataFetch = await fetch(url, {
method: "Get",
headers: {
Accept: "application/json",
Authorization: auth,
},
});
// api拿到之後轉乘json格式
let parseData = await dataFetch.json();
console.log(parseData.photos);
setData(parseData.photos);
};// load more pic
/**
* 更多精選
* 更多搜尋相關
*/
const morepic = async () => {
let newURL;
if (input === "") {
newURL = `https://api.pexels.com/v1/curated?page=${page}&per_page=15`;
} else {
newURL = `https://api.pexels.com/v1/search?query=${currentSearch}&per_page=15&page=${page}`;
}
setPage(page + 1);
const dataFetch = await fetch(newURL, {
method: "Get",
headers: {
Accept: "application/json",
Authorization: auth,
},
});
let parseData = await dataFetch.json();
// 必須用concat串接上面的data
// 另外就是data因為前面刷新頁面執行過了 所以裡面一定有東西
setData(data.concat(parseData.photos));
};// 頁面刷新自動上照片 useEffect
// 注意useEffect裡面要放arrow
// 同時也處理current Search的閉包問題
useEffect(() => {
if (input === "") {
search(initialURL);
} else {
search(searchURL);
}
}, [currentSearch]);/**
* 將data以變數的形式丟回到photo使用
* 以維持state階級
* search setInput也是
*/
return (
{/* 搜尋的變數必須由這裏去接,但由下一層啟動
所以設定一個arrow去做
*/}
{
// 就算這裡做更改 searchURL依然會抓到最前面部分
// 因為JS的closure特性 他會先跳去上一層找searchURL,而非先執行新的URL,所以建議用useEffect
setcurrentSearch(input);
// search(searchURL);
}}
setInput={setInput}
/>
{
/* react的特殊技巧,因為下面的串接會因為data預設為null,
而不能用map抱錯。這裡可以用and運算的方式,把null出現的部分,
連同後面的map一起false掉,這樣就不會執行 */
data &&
data.map((d) => {
return ;
})
}
more pictures
);
};export default Homepage;
```Search.jsx
```jsx
import React, { useState } from "react";const Search = ({ search, setInput }) => {
// 把輸入格的東西抓近來
// 透過js的節點去抓
// 必須以arrow function去做 以確保執行面
const inputHandler = (e) => {
setInput(e.target.value);
};return (
Search
);
};export default Search;
```Photo.jsx
```jsx
import React from "react";const Photo = ({ data }) => {
return (
);
};export default Photo;
```