這篇文章主要是紀錄一些初始化的步驟,包含了最初的安裝環境,編輯器、node、TypeScript、tailwindCSS、styledComponents,建立React專案,一些React套件Router、Redux。並不解釋這些使用的方式,主要是給學過的(我)快速搜尋想要的工具,想要學習詳細內容分別有各自的文章可以索引
內容目錄
環境安裝
- vscode
- nodeJS
- TypeScript
參考:【TypeScript學習系列】快速安裝TypeScript開發環境,輕鬆建立第一個TS專案
安裝React
使用Create React App提供的指令,建立react檔案
npx create-react-app my-app --template typescript
檔案初始化
刪除不必要的部分
檔案
- reportWebVitals.ts
- setupTests.ts
- App.test.tsx
- logo.svg
程式碼
index.tsx
import reportWebVitals from './reportWebVitals';
reportWebVitals();
App.tsx
import logo from './logo.svg';
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
App.css
全刪除
安裝tailwindCSS或styled-components
兩者擇一,看專案需求
tailwindCSS
依照官網的安裝流程
安裝指令
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
};
Index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
VScode套件安裝
- Tailwind CSS IntelliSense
styled-components
依照官網的安裝流程
參考:【React學習系列】學習React組件,讓你的UI分離,把HTML跟CSS都寫進JS裡
安裝指令
npm install --save styled-components @types/styled-components
使用styled-components的檔案
import styled from "styled-components";
VScode套件安裝
- styled-components-snippets
安裝React Router
依照官網的安裝流程
參考:【React學習系列】使用React Router套件簡單達成頁面跳轉畫面
安裝指令
npm install react-router-dom@6
Index.html
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
,
</React.StrictMode>,
document.getElementById("root")
);
使用方法
App.tsx
import { Routes, Route, Link } from "react-router-dom";
設定路徑程式碼
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />}>
<Route path=":Item" element={<Item />} />
</Route>
</Routes>
跳轉程式碼
<Link to="/about">About</Link>
多個路徑
App.tsx
設定路徑程式碼,是在About頁面裡在插入一個分頁內容Main
路徑為 /about/main
import { Routes, Route, Link, Outlet } from "react-router-dom";
<Route path="about" element={<About />}>
<Route path="main" element={<Main />} />
</Route>
父頁面顯示子頁面的位置
到父組件中,新增這個組件,可以讓子組件顯示在父組件設定的位置
<Outlet />
config用法
App.tsx
以下都是在App.tsx檔案作業
import { RouteObject, useRoutes,} from "react-router-dom";
宣告
let routerConfig: RouteObject[] = [
{
path: "/",
element: <Home />,
},
];
實作
const elements = useRoutes(routerConfig);
App組件使用
{elements}
安裝Json Server
依照npm網站的安裝流程
輸入指令,安裝Json Server到全域中
npm install -g json-server
建立db.json檔案,並且輸入測試程式碼
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
輸入指令,即可獲得網址
- http://localhost:3000/posts
- http://localhost:3000/comments
- http://localhost:3000/profile
json-server --watch db.json
※額外 到package.json的scripts中輸入程式碼,即可輸入指令npm run server就可以獲得網址
"server": "json-server --watch db.json"
安裝react-redex
依照官網的安裝流程
參考:
Redux Toolkit及Redux的安裝指令
npm install @reduxjs/toolkit
React-Redux的安裝指令
※最後報出module not found: error: can’t resolve ‘react-redux’ in的錯誤就安裝npm install react-redux
npm install @types/react-redux
npm install react-redux
Devtools的安裝指令
npm install --save-dev @redux-devtools/core
Chrome套件安裝
- Redux Devtools
檔案建立
app/store.ts
import { configureStore } from "@reduxjs/toolkit";
// ...
import SliceReducer from "../features/counter/counterSlice";
export const store = configureStore({
reducer: {
SliceReducer,
},
});
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;
app/hooks.ts
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
features/ counter/ counterSlice.ts
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "../../app/store";
// Define a type for the slice state
interface CounterState {
value: number;
}
// Define the initial state using that type
const initialState: CounterState = {
value: 0,
};
export const counterSlice = createSlice({
name: "counter",
// `createSlice` will infer the state type from the `initialState` argument
initialState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
// Use the PayloadAction type to declare the contents of `action.payload`
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
Index.tsx
import { Provider } from "react-redux";
import { store } from "./app/store";
<Provider store={store}>
<App />
</Provider>
使用Hook取值、執行dispatch
取值
App.tsx
import { useAppSelector } from "./app/hooks";
const select = useAppSelector((state) => {
return state.SliceReducer;
});
執行dispatch
App.tsx
import { useAppDispatch } from "./app/hooks";
import { increment } from "./features/counter/counterSlice";
const dispatch = useAppDispatch();
dispatch(increment());
使用中間層Middleware
App.tsx
import { Middleware } from "redux";
export const logger: Middleware = (store) => (next) => (action) => {
console.log("dispatching", action);
let result = next(action);
console.log("next state", store.getState());
return result;
};
app/store.ts
import { logger } from "../middleware/middleware";
export const store = configureStore({
reducer: {
SliceReducer,
},
middleware: (getMiddleware) => {
return getMiddleware().concat(logger);
},
});
export default store
app/store.ts
處理類型問題
import { combineReducers } from "redux";
const rootReducer = combineReducers({ SliceReducer });
export const store = configureStore({
reducer: rootReducer,
middleware: (getMiddleware) => {
return getMiddleware().concat(logger);
},
});
export type RootState = ReturnType<typeof rootReducer>;
RTA Query
server/serverAPI.ts
- 修改變數
- reducerPath的值
- 網址
- export規則是endpoints的function名 = use”function名” Query
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
// import { Pokemon } from "./types";
export const serverAPI = createApi({
reducerPath: "serverAPI",
baseQuery: fetchBaseQuery({
baseUrl: "https://jsonplaceholder.typicode.com/",
}),
endpoints: (builder) => ({
// getPokemonByName: builder.query<Pokemon, string>({
// query: (name) => `pokemon/${name}`,
todoList: builder.query<any, string>({
query: (id) => `todos/${id}`,
}),
}),
});
export const { useTodoListQuery } = serverAPI;
app/store.ts
import { serverAPI } from "../server/serverAPI";
const rootReducer = combineReducers({
[serverAPI.reducerPath]: serverAPI.reducer,
});
export const store = configureStore({
reducer: rootReducer,
middleware: (getMiddleware) => {
return getMiddleware().concat(serverAPI.middleware)
},
});
App.tsx
- 修改為import自訂義的hook
import {useTodoListQuery} from './server/serverAPI'
const { data, error, isLoading } = useTodoListQuery("1");
console.log("data", data);
console.log("error", error);
console.log("isLoading", isLoading);
結論
這些都是我在布魯斯的 TypeScript 入門攻略|輕鬆打造實時聊天室及布魯斯的 TypeScript + React 全攻略|快速上手仿 Instagram UI這兩堂課程中學習到一些套件及環境安裝快速總結,基本的概念都已經課程中學習過,並且記錄在不同的文章中,以方便後續查找,那這也是為了讓我以後可以快速建立這些套件,所撰寫文章,才不會在各篇文章中翻找半天,真的有需要、忘記了內容才會在去翻看課程跟其他文章
能達到這樣的學習成效,我覺得布魯斯這兩堂課功不可沒,透過課程的學習,打下深厚的基礎跟印象,將來要再延伸學習就會相對容易,從零到一的過程是最難的,透過這兩堂課,則是幫我實現了這樣的過程,非常推薦學習