0. redux要点
1. redux理解
2. redux相关API
3. redux核心概念(3个)
4. redux工作流程
5. 使用redux及相关库编码
#1. redux理解 什么?: redux是专门做状态管理的独立第3方库, 不是react插件 作用?: 对应用中状态进行集中式的管理(写/读) 开发: 与react-redux, redux-thunk等插件配合使用
2. redux相关API
redux中包含: createStore(), applyMiddleware(), combineReducers()
store对象: getState(), dispatch(), subscribe()
react-redux: <Provider>, connect()()
3. redux核心概念(3个)
action:
默认是对象(同步action), {type: 'xxx', data: value}, 需要通过对应的actionCreator产生,
它的值也可以是函数(异步action), 需要引入redux-thunk才可以
reducer
根据老的state和指定的action, 返回一个新的state
不能修改老的state
store
redux最核心的管理对象
内部管理着: state和reducer
提供方法: getState(), dispatch(action), subscribe(listener)
4. redux工作流程
5. 使用redux及相关库编码
需要引入的库:
redux
react-redux
redux-thunk
redux-devtools-extension(这个只在开发时需要)
redux文件夹:
action-types.js
actions.js
reducers.js
store.js
组件分2类:
ui组件(components): 不使用redux相关PAI
容器组件(containers): 使用redux相关API
6.项目头部切换
import React,{Component} from 'react'
import Logo from './images/logo.png'
import {withRouter} from 'react-router-dom'
import {connect} from 'react-redux'
import {getHeadCateList} from '../../redux/actions'
import BScroll from 'better-scroll'
import './headertop.less'
class HeaderTop extends Component{
state = {
targetIndex:0
}
componentWillMount(){
this.setState({
targetIndex: sessionStorage.getItem('INDEX')*1
}, () => {
console.log(this.refs.list.children, 'xxxxx');
window.requestAnimationFrame(this.updateClass)
})
}
componentDidMount(){
this.props.getHeadCateList()
}
componentDidUpdate() {
//单例对象可以实现不重复创建,加判断
if(!this.scrollId){
this.scrollId=new BScroll('.nav_wrapper',{
probeType: 2,
scrollX:true,
click: true,
eventPassthrough:'vertical'
})
}
}
goTj=()=>{
this.props.history.replace('/recommend')
sessionStorage.setItem('INDEX', 0);
this.setState({
targetIndex:0
}, () => {
this.updateClass();
})
}
change=(url,targetIndex)=>{
this.props.history.replace(url)
sessionStorage.setItem('INDEX', targetIndex);
this.setState({
targetIndex:targetIndex
}, () => {
this.updateClass();
})
}
updateClass = () => {
let lis=this.refs.list.children;
if(lis.length <=1){
window.requestAnimationFrame(this.updateClass);
}
console.log(lis, '再次测试', this.state.targetIndex);
lis=Array.from(lis);
console.log(lis);
lis.forEach((item, index) => {
console.log(item, index);
item.className='';
item.className='slide_item';
if(index===this.state.targetIndex){
item.className='slide_item active';
}
})
}
render(){
let {headCateList} = this.props;
if(!headCateList){
headCateList = [];
}
return(
<div className="header_wrapper">
<div className="large_header">
<div className="header">
<div className="logo" onClick={this.goto}>
<img src={Logo} alt="" />
</div>
<div className="search">
<i className="iconfont icon-search"></i>
<span className="placeholder">搜索商品, 共10718款好物</span>
</div>
</div>
<div className="nav_wrapper">
<ul ref='list' className="slide_nav">
<li className={`slide_item ${(this.props.location.pathname.length===10)? 'active':''}`}
onClick={this.goTj} >推荐</li>
{
headCateList.map((headCate,index)=>(
<li key={index} onClick={()=>this.change(`/athome/${headCate.id}`,index+1)}>
{headCate.name}
</li>
))
}
</ul>
</div>
</div>
</div>
)
}
}
export default connect(
state=>({headCateList:state.headCateList}),
{getHeadCateList}
)(withRouter(HeaderTop))