配置開發環境
腳手架工具create-react-app
儲備知識:終端或命令列、程式碼編輯器
create-react-app
其是基於Node的快速搭建React專案的腳手架工具。
npx create-react-app testdemo
cd testdemo
npm i
npx命令是npm v5.2.0引入的一條命令,無需安裝腳手架包,就可以直接使用這個包提供的命令
yarn是Facebook釋出的包管理器,功能與npm相同,具有快速、可靠和安全的特點
React with TypeScript
npx create-react-app testdemo-ts --template typescript
cd testdemo
npm i
About TypeScript
- TypeScript是JavaScript的超集
- 給原生JavaScript新增型別檢查
- 與ES6一樣目前無法被主流瀏覽器直接讀取
Compile TypeScript
編譯器:ts-loader、awesome-typescript-loader以及babel-loader
編譯器配置檔案:tsconfig.json
{
"compilerOptions": {
"noImplicitAny": false, //不需要顯示地宣告變數的型別any
"target": "es5", //編譯後的目標js版本
"lib": [
"dom",
"dom.iterable",
"esnext"
], //庫檔案,過這些庫檔案,告訴typescript編譯器可以使用哪些功能
"allowJs": true, //允許混合編譯js檔案
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true, //允許使用commonJs方式import預設檔案
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext", //配置程式碼模組系統,Node.js的commonJs、ES6的esnext、requireJs的AMD
"moduleResolution": "node",// 決定編譯器的工作方式
"resolveJsonModule": true,
"isolatedModules": true, //編譯器會將每個檔案作為單獨的模組使用
"noEmit": true, //發生錯誤時候,編譯器不會生成Js程式碼
"jsx": "react-jsx" //允許編譯器支援編譯react程式碼
},
"include": [
"src"
] //使用此選項列出我們需要編譯的檔案, “檔案路徑”選項需要檔案的相對或絕對路徑
}
Update to TypeScript
1、npm install --save typescript @types/node @types/react @types/react-dom @types/jest
2、所有js檔案改為jsx檔案
3、import react
React基礎
About React
History of FE
HTML、CSS、JavaScript——Ajax——jQuery——Angular MVC——Vue、React MVVM
Why is React?
- 單向資料流
- 你只需要描述UI(HTML)看起來是什麼樣子,就和寫HTML一樣
- React負責渲染UI,並在資料變化時更新UI
- 虛擬DOM
類似於Docker或VMware的Snapshot的快照技術
- 元件化
- 保持互動的一致性
- 保持視覺風格的統一
- 便於程式設計師之間的協作
- 學習一次,隨意使用(必殺技)
- 使用React可以開發Web應用
- 使用React可以開發移動端原生應用(react-native)
- 使用React可以開發VR(虛擬現實)(react 360)
What is React?
React是一個用於構建使用者介面(HTML頁面)的JavaScript庫
主要用來寫HTML頁面,或構建Web應用
如果從MVC角度來看,React僅僅是檢視層(V),只負責檢視的渲染,不提供完整的M和C的功能
(經典MVC模式中,M是指業務模型,V是指使用者介面,C則是控制器,使用MVC的目的是將M和V的實現程式碼分離,從而使同一個程式可以使用不同的表現形式。)
起源:Facebook的內部專案
JSX
What is JSX?
What's this?HTML?JS?
const element = <h1>Hello,world!</h1>
這是ReactJS自創的語言:JSX
- JSX不是標準的ECMAScript語法,只是語法擴充套件
- 對於React專案使用js和jsx都可以
- ts對應tsx語法
JSX 其實是React.createElement
的語法糖,下圖的兩種寫法完全等價:
Why is JSX?
- React並不強制使用JSX,也可以使用原生的JavaScript
- React認為檢視的本質是:渲染邏輯與UI檢視表現的內在統一
- React把HTML與渲染邏輯進行了耦合,形成了JSX
Features of JSX
- HTML程式碼可以與JSX相容
- 可以在JSX中嵌入表示式
- 使用JSX指定子元素
Attention
- React元素的屬性名使用小駝峰命名法
- 特殊的屬性名:class->className、for->htmlFor、tabindex->tabIndex
- 如果元素沒有子節點可以用
/>
結束 - 推薦使用小括號包裹JSX,從而避免JS中的自動插入分號陷阱
基本使用
JXS中使用(嵌入)Js表示式
資料儲存在JS中,語法:{JavaScript表示式} 注意:語法是單大括號
const name = '張三'
// 1、使用JSX建立react元素
const title = <h1>Hello {name}</h1>
//2、渲染react元素
ReactDOM.render(title, document.getElementById('root'))
React DOM 在渲染所有輸入內容之前,預設會進行轉義。它可以確保在你的應用中,永遠不會注入那些並非自己明確編寫的內容。所有的內容在渲染之前都被轉換成了字串。這樣可以有效地防止 XSS(cross-site-scripting, 跨站指令碼)攻擊。
擴充閱讀:如何防止XSS攻擊?
JSX的條件渲染
- 場景:loading效果
- 條件渲染:根據條件渲染特點的JSX結構
- 可以使用if/else或三元運算子或邏輯與運算子來實現
const loadData = () => {
if (loading) {
return <div>loading...</div>
}
return <div>資料載入完成</div>
}
JSX的列表渲染
- 應該使用陣列的map()方法(對映)
- 渲染列表時應該新增key屬性,key屬性的值要保證唯一
- 原則:map()遍歷誰,就給誰加key屬性
- 注意:儘量避免使用索引號作為key
const songs = [
{ id: 1, name: '愛你' },
{ id: 2, name: '年少有為' },
{ id: 3, name: '南山南' },
]
// 1、使用JSX建立react元素
const list = (
<ul>
{songs.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
)
JSX的樣式處理
CSS of React
The way of import css file
- 直接引入整個css檔案
import './index.css'
<div className="app">
使用簡單,但可能會造成樣式的全域性汙染和樣式衝突。
- JSS模組化引入元件
import style from './index.css'
<div className={style.app}>
需要額外配置,ts環境需要配置*.d.ts
的型別宣告檔案
declare module "*.css" {
const css: {
[key: string]: string //約定:匯出key所在的物件,原始的類名和內容都會和轉化為這個物件
};
export default css;
}
CSS module/JSS
- 每個jsx或tsx檔案被視為一個獨立存在的原件
- 原件所包含的所有內容也同樣都應該是獨立存在的
擴充閱讀:CSS in Js
CSS & TypeScript
Ts的優勢就是給Js進行型別檢查,那麼透過JSS將CSS轉換為Js物件,是不是也可以給CSS新增型別?
外掛:typescript-plugin-css-modules
npm i typescript-plugin-css-modules --save-dev
在tsconfig.json檔案compilerOptions新增:
"plugins": [{
"name":"typescript-plugin-css-modules"
}]
新建.vscode資料夾——新建檔案settings
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
配置後會發現編寫style也會有隻能提示
Media & fonts
src/assets/images
src/assets/fonts
src/assets/icons
State & Props
Difference
- props是元件對外的介面,而state是元件對內的介面
- props用於元件間的資料傳遞,而state用於元件內部的資料傳遞
State
State是元件的“私有屬性”
初始化
//建構函式constructor是唯一可以初始化state的地方
constructor(props){
super(props);
this.state = {
count: 0
}
}
修改
//使用setState()修改資料,更新元件狀態,呼叫render函式重新渲染
onClick = {() => {
this.setState({isOpen: !this.state.isOpen});
}}
非同步更新 同步執行
呼叫setState後,state不會立即改變,是非同步操作(React會將多個修改合併為一個)。所以,不要依賴當前的State,計算下個State。
setState本身並非非同步,但對state的處理機制給人一種非同步的假象。
onClick = {() => {
this.setState((preState, preProps) => {
return {count: preState.count + 1}
},() => {
console.log("count" ,this.state.conut)
});
this.setState((preState, preProps) => {
return {count: preState.count + 1}
},() => {
console.log("count" ,this.state.conut)
});
}}
Props
本質上,props就是傳入函式的引數,是父元件傳向子元件的資料。
父元件
<ul>
{robots.map(r => <Robot id={r.id} name={r.name} email={r.email}></Robot>)}
</ul>
子元件
//為Robot指定型別React.FC,FC(functional component)函式式元件的介面,接受泛型引數P(Props)
const Robot: React.FC<RobotProps> = (props) => {
const id = props.id;
const name = props.name;
const email = props.email;
return (<div className={styles.cardContainer}>
<img src={`https://robohash.org/${id}`} alt="robot" />
<h2>{name}</h2>
<p>{email}</p>
</div>
);
}
Immutable
props是只讀的,一旦建立不可被改變,只能透過銷燬、重建來改變資料。
優點:透過判斷記憶體是否一致,來確認物件是否有經過修改,極大提高效能效率
使用Immutable來編寫程式的方式就是函數語言程式設計(元件)。