配置開發環境 腳手架工具create-react-app 儲備知識:終端或命令行、代碼編輯器 React官方中文文檔 create-react-app 其是基於Node的快速搭建React項目的腳手架工具。 npx create-react-app testdemo cd testdemo npm ...
配置開發環境
腳手架工具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來編寫程式的方式就是函數式編程(組件)。