reacy初体验,总结记录
redux
安装redux以及调试工具
1 | yarn add redux redux-react --save |
redux基本使用
- 1 创建Action模块
- 2 创建Reducer模块 处理业务数据
- 3 创建Store模块 数据源
- 4 通过Provider作为项目的跟组件,用于数据的存储
- 5 通过connect方法将React组件和Redux连接起来
- 目录结构
1
2
3
4
5
6
7
8
9
10
11├── redux
│ ├── action
│ │ ├── home.js
│ │ ├── user.js
│ ├── reducer
│ │ ├── home.js
│ │ ├── user.js
│ │ ├── index.js
│ ├── store.js
├── index 根组件1 创建Action模块
- action/home.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21import * as Types from '../action-types'
// actionCreators 构建action对象的 他是一个function
export const setCurrentLesson = (val)=>{
return {
type:Types.SET_CURRENT_LESSON,
val:val
}
};
//redux-thunk要求返回两层函数
//如果使用redux-thunk\actionCreators可以返回一个函数 函数中有dispath参数
export const getSilder = ()=> (dispath)=>{
//在action里发送异步请求获取数据在dispath发送到reducers里去
getSilders().then(silders=>{
console.log(silders);
dispath({
type:Types.GET_SLIDERS,
silders:silders
})
})
} - user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import * as Types from '../action-types';
import {regs,auths} from '../../api/user';
//验证是否登陆
export const auth = ()=> (dispath)=>{
auths().then(data=>{
if(data.username){
util.set('user',data);//备用数据信息
dispath({
type:Types.SET_USER_INFO,
userInfo:data
})
}else{
//如果没登陆 去登录页
}
})
}2 创建Reducer模块 处理业务数据
- home.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28// 初始状态
let initState = {
currentLesson:0,//当前课程
silders:[],//轮播图数据
lesson:{
lessonList:[],//课程数据
hasMore:true,//是否加载更多数据
limit:5 ,//每次要5条数据
offset:0, //跳过多少页 偏移量
isLoading:false //是否正在加载
}
};
export default function(state = initState,action){
switch (action.type){
case Types.SET_CURRENT_LESSON:
return {
...state,
currentLesson:action.val,
lesson:{
...state.lesson,
lessonList:[],
offset:0,
}
}
default:
return state;
}
} - user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import * as Types from '../action-types'
let initState= {
userInfo:{//用户的信息
},
err:'' //登陆错误的信息
};
//注册
export default function(state=initState,action){
switch (action.type){
case Types.SET_ERROR:
return {...state,err:action.error}
case Types.SET_USER_INFO:
return {...state,userInfo:action.userInfo,err:''}
default:
return state;
}
}reducer/index.js合并状态树
1
2
3
4
5
6
7
8
9
10
11/**
* 因为有很多状态树 需要合并combineReducers
* reducer管理员
*/
import {combineReducers} from 'redux'
import home from './home'
import user from './user'
export default combineReducers({
home,
user
})3 创建Store模块 数据源
1
2
3
4
5
6
7
8
9import reducers from './reducers'
//createStore存储数据的 相当于创建工厂
import {createStore,applyMiddleware} from 'redux';
//异步需要redux的中间件applyMiddleware
//运行action自定义dispath(actions中的dispath事件)
//如果运行这个中间件会传参数dispath可以手动发布action
import reduxThunk from 'redux-thunk'
export default createStore(reducers,applyMiddleware(reduxThunk))4 通过Provider作为项目的根组件index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14import React from 'react';
import ReactDOM from 'react-dom';
import Router from './router'
//获取store的数据源对象 提供数据源
import { Provider } from 'react-redux';
//redux 引入数据源
import store from './redux/store'
window._store = store; //_store.getState()
ReactDOM.render(
//Provider提供数据源 这样所有的组件都可以拿到数据源了
<Provider store={store}>
<Router />//路由
</Provider>, document.getElementById('root'));5 通过connect方法将React组件和Redux连接起来
- this.props.setCurrentLesson(type)调用actions的方法
- this.props.home.silders调用reducers中home.js中的silders数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import React, { Component } from 'react'
//通过connect(redux连接器)使react关联redux 点击的时候需要触发action 引入action
import { connect } from 'react-redux'
class Home extends Component {
render() {
chooseLesson = (type)=>{//点击导航选择课程 将这个方法传给子级;
//dispath一个action 依赖connect传入一个方法到action文件下的home
//然后 构建action对象跑到reducer
//reducer会走到reducers文件夹下的home.js\
//reducer判断完会更改状态 状态改变值就会发生变化
this.props.setCurrentLesson(type)//点击导航获取到type类型
console.log(window._store.getState());//reducers下的currentLesson是2
}
return (
<div className='header'>
<Swiper data={ this.props.home.silders}></Swiper>
</div>
)
}
// 参数1 mapStateToProps将redux中的数据变成属性
// 参数2 mapDispatchToProps 可以直接传一个actionCreator的对象
//(actionCreator是函数 函数上套个对象)
// 参数3 Home当前组件名
// ...state将所有属性解构出来 单写connect(state=>({currentLesson:state.home.currentLesson}))
// 第二个参数可以使 this.props.setCurrentLesson直接由action导入的方法
//(会自动把对象放到props属性上去)
//同步的
export default connect(state=>({...state}),action)(Home)