cnpm i -g create-react-app
create-react-app react-family
cd react-family
npm start
如果需要配置脚手架
npm run eject
cnpm install redux --save
cnpm install react-redux --save
cnpm install redux-thunk --save//异步任务需要中间件
cnpm install react-router-dom --save
npm install antd-mobile --save//蚂蚁金服ui库
npm install babel-plugin-import --save//按需加载组件代码和样式的 babel 插件
配置package.json
"plugins": [
["import", { libraryName: "antd-mobile", style: "css" }] // `style: true` 会加载 less 文件
]
npm install express --save
1.Redux专注于状态管理,和react解耦
2.单一状态,单向数据流
3.核心概念: store,state, action, reducer
npm i redux --save
1.创建store
import { createStore } from 'redux'
2.编写reducer
function counter(state=0,action) {
switch(action.type) {
case
return state+1
case
return state+1
default
return 10
}
}
const store = createStore(counter)
const init = store.getState()
console.log(init) //10
控制台可以看见打印初始状态10 3.派发事件 传递action
store.dispatch({type:'加'})
console.log(store.getState())
store.dispatch({type:'减'})
console.log(store.getState())
可以看出通过dispatch改变state的值 4.通过subscribe监听变化
functin listener(){
const current = store.getState()
}
store.subscribe(listener)
1.把store.dispatch方法传递给组件,内部可以调用修改状态 2.subscribe订阅 render函数,每次修改都重新渲染 新建index.redux.js
const ADD_GUN = '加'
const JIAN_GUN = '减'
export function counter(state=0,action) {
switch(action.type) {
case ADD_GUN:
return state+1
case JIAN_GUN:
return state-1
default:
return 10
}
}
export function add() {
return { type: ADD_GUN}
}
export function jian() {
return { type: JIAN_GUN}
}
在app.js里调用dispatch
import React, {Component} from 'react'
class App extends Component{
render() {
const store = this.props.store
const num = store.getState()
const add = this.props.add
const jian = this.props.jian//纯组件,只依赖付组件传递
return(
<div>
<h1>当前状态是{num}</h1>
<button onClick={()=>store.dispatch(add())}>加</button>
<button onClick={()=>store.dispatch(jian())}>减</button>
</div>
)
}
}
npm i redux-thunk --save
在创建store时引入中间件
import {applyMiddleware} from 'redux'
import { thunk } from 'redux-thunk'
const store = createStore(counter, applyMiddleware(thunk))//可以处理异步请求
在index.redux.js中添加异步reducer
erport function addAsync() {
return dispatch=>{
setTimeout(()=>{
dispatch(add())
})
}
}
在app.js里调用
const addAsync = this.props.addAsync
<button onClick={()=>store.dispatch(addAsync())}>addAsync</button>
1.在index.js文件里
import { compose } from 'redux'//组合函数
const reduxDevtools = window.devToolsExtension?window.devToolsExtension():() => {}
const store = createStore(counter, compose(
applyMiddleware(thunk),reduxDevtools
))
npm install react-redux --save
忘记subscribe,记住reducer、action和dispatch
react-redux提供Provider和connect两个接口来链接
Provider组件在应用最外层,传入store即可,只用一次
Connect复制从外部获取组件需要参数
在index.js里
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>,
document.getElementById("root")
);
在app.js
import { connect} from 'react-redux'
import {add, jian, addAsync } from './index.redux'
App = connect()(App)//装饰器可以传4个参数
const mapStateToProps=(state)=>{
return {num: state}
}
const actionCreators = { add, jian, addAsync }
App = connect(mapStateToProps, actionCreators)(App)
此时不需要dispatch
render() {
const num = this.props.num
const add = this.props.add
const jian = this.props.jian
const addAsync = this.props.addAsync
return (
<div>
<div>当前状态{num}</div>
<button onClick={add}>加</button>
<button onClick={jian}>减</button>
<button onClick={addAsync}>addAsync</button>
</div>
);
npm run eject弹出个性配置
npm i --save-dev babel-plugin-transform-decorators-legacy
// 支持装饰器插件
改进connect
const mapStatetoProps= (state) =>{
return {num:state}
}
const actionCreaters = {add, jian, addAsync }
之前
App = connect(mapStatetoProps,actionCreaters)(App)
现在
@connect(mapStatetoProps,actionCreaters)// 传入需要的属性和方法
动态路由、Route、Link、Switch
1.安装
npm i react-router-dom --save
入门组件
BrowserRouter包裹整个应用
Route路由对应渲染的组件,可嵌套
link跳转专用
在index.js
import { BrowserRouter, Route, Link} from 'react-router-dom'
<Provider store = {store}>
<BrowserRouter>
<div>
<ul>
<li>
<Link to="/">首页</Link>
</li>
<li>
<Link to="page1">page1</Link>
</li>
<li>
<Link to="page2">page2</Link>
</li>
</ul>
<Route path="/" exact component={App}></Route>
<Route path="/page1" component={Page1}></Route>
<Route path="/page2" component={Page2}></Route>
</div>
</BrowserRouter>
</Provider>,
一般组件不能获取history
可以通过
import { withRouter } from 'react-router-dom'