React
有關使用包
- 使用官方提供的react腳手架搭建的小型專案:create-react-app
- react中使用路由react-router-dom
- 單向資料流使用的是redux,通過redux-thunk中介軟體實現非同步操作
- 使用單向資料流與路由中,通過props逐級傳遞有點麻煩,效能不佳,使用中介軟體形式的react-redux構造裝飾器,可以訪問全域性資料流
-
在react專案中還是用了懶載入react-loadable
import Loadable from `react-loadable` const Loading = ({ //自定義公用載入時頁面 pastDelay, timedOut, error }) => { if(pastDelay) { return <div></div>; } else if(timedOut) { return <div>Taking a long time...</div>; } else if(error) { return <div>Error!</div>; } return null; } //路由中頁面 懶載入 view const MusicIndex = Loadable({ loader: () => import(`./component/MusicIndex/MusicIndex`), loading: Loading, timeout: 10000 })
react中的生命週期
# react 的基本元件生命週期如下
1. constructor 元件的建構函式:接受父元件的引數,初始化state,繫結函式等等的操作
2. componentWillMount 元件渲染之前,每次元件渲染都會觸發一次
3. componentDidMount 元件渲染之後,每次元件渲染都會觸發一次,子元件都掛載好,可以使用refs,可以使用非同步方法,防止阻塞UI
4. componentWillReceiveProps 該函式接收到新的props才會被呼叫,render不會觸發該函式
5. shouldComponentUpdate 在元件接收到新的props或者state時被呼叫。在初始化時或者使用forceUpdate時不被呼叫。
6. componentWillUpdate 該函式接收到新的props或者state與render之前才會被呼叫,初始化不會觸發該函式
7. componentDidUpdate 該函式在元件完成更新後立即呼叫。在初始化時不會被呼叫。
8. componentWillUnmount 該函式為元件被移除(解除安裝)時被呼叫
class App extends Component {
constructor(props) {
super(props)
}
componentWillMount(){}
componentDidMount() {}
componentWillReceiveProps(newProps) {}
shouldComponentUpdate(newProps, newState) {
return true;
}
componentWillUpdate(nextProps, nextState) {}
componentDidUpdate(prevProps, prevState) {}
componentWillUnmount() {}
render() {
return(
<div className="App">展示APP頁面</div>
);
}
}
react中使用路由
import { HashRouter as Router, Route, Link } from "react-router-dom"
import { MusicIndex } from "./../MusicIndex.js"
import { MusicRanking } from "./../MusicRanking.js"
import { MusicCollection } from "./../MusicCollection.js"
import { MusicPersonal } from "./../MusicPersonal.js"
render() {
return(
<div className="App">
<Router>
<div className="app-box-view">
<Route exact path="/" component={ MusicIndex } />
<Route path="/ranking" component={ MusicRanking } />
<Route path="/collection" component={ MusicCollection } />
<Route path="/personal" component={ MusicPersonal } />
</div>
</Router>
<div className="App-tabbar">
<span onClick={ window.location.hash = `/`}>頁面一</span>
<span onClick={ window.location.hash = `/ranking`}>頁面二</span>
<span onClick={ window.location.hash = `/collection`}>頁面三</span>
<span onClick={ window.location.hash = `/personal`}>頁面四</span>
</div>
<Audio></Audio>
</div>
);
}
react中使用單向資料流redux
redux
-
redux分為3各部分
- store :資料,store全域性僅有唯一的store
- action: 操作,通過觸發action改變store的狀態,stroe的狀態不能不能直接修改
- Reducers 執行,通過action反饋的操作去執行,直接修改store的狀態
- redux 在大型專案中可與 vuex 一樣實現模組化管理。redux 通過自帶的函式 combineReducers 對自身切割分為多個模組。
redux例子
1. redux分割例子
import { combineReducers } from "redux"
import { albumItem } from `./reducers/MusicAlbumItem`
import { ranking } from `./reducers/MusicRanking`
import { user } from `./reducers/MusicUser`
import { collection } from `./reducers/MusicCollection`
export const rootReducer = combineReducers({
player,
ranking,
user,
collection
})
2. 單獨分割出來redux的例子
const R_CHANGE = "改變快取排行版"
const R_INIT = "重置排行版"
const R_LOADING = "排行版列表加在完畢"
//以下為store
let rankingStore = {
rank:[],
target:{
id:0,
playlist:{}
},
loading:true
}
//以下為reducers
export const ranking = (state = rankingStore, action) => {
switch(action.type) {
case R_INIT:
state.rank = action.list
return Object.assign({}, state)
case R_CHANGE:
state.target = action.list
return Object.assign({}, state)
case R_LOADING:
state.loading = false
return Object.assign({}, state)
default:
return state
}
}
//以下為action
export function r_change(list) {
return {
type: R_CHANGE,
list:list
}
}
export function r_init(list) {
return {
type: R_INIT,
list:list
}
}
export function r_loading() {
return {
type: R_LOADING
}
}
redux如何被不同路由下的元件使用與訪問
- 在react的入口檔案中注入store,使其可以被全域性路由訪問
- 在對應的元件中引入需用的actino,stroe是直接訪問全域性的,action是按需引入
- 以下為例子
import React from `react`;
import ReactDOM from `react-dom`
import { createStore, applyMiddleware, compose } from `redux`
import { BrowserRouter } from `react-router-dom`
import registerServiceWorker from `./registerServiceWorker`
import `./index.css`
import App from `./App`
import { rootReducer } from `./redux/index`
import thunk from `redux-thunk`
import { Provider } from `react-redux`
const store = createStore(rootReducer, compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
))
//通過路由注入store,使其可被全域性訪問stroe(前提是需訪問的元件引入對應的redux)
ReactDOM.render(
(<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>),
document.getElementById(`root`)
);
react可優化的各方面
- 在react 16 之前的版本可以通過簡單的遍歷元件中的props或者state資料的變化監聽資料是否被更新,來控制元件的渲染,一個正常的元件在父元件的狀態被改變的情況下,會觸發render,如果是列表之類的元件render多了就會效能差,可以通過 shouldComponentUpdate 鉤子函式來決定元件是否接受更新
- 在react 16後,官方提出類似Component的介面 PureComponent,react可以自動幫你決定元件是否接受更新
- 在元件的使用時,必須對其賦於 全域性唯一的KEY。在列表的渲染中不推薦使用迴圈的下標作為 key 在列表的渲染中,如果對列表某條資料刪除會改變其上下的元件的 key 改變
- 增大元件的複用性