function createStore(reducer){
let state;
getState = () => state;
let listeners = [];
let dispatch = function(action){
state = reducer(state,action);
listeners.forEach(fn=>fn())
}
<!--默认状态state-->
dispatch({type:'@INIT'})
let subscribe = function(fn){
listeners.push(fn);
return function(){
listeners = listeners.filter(l=>l!=fn)
}
}
return {
getState,
subscribe,
dispatch
}
}
复制代码
reducer自己是一个函数,传递两个参数,分别为state和action,而后判断action.type来进行不一样的逻辑来改变statereact
import * as Types from '../action-types'
function counter(state = {number:0},action){
switch(action.type){
case Types.INCREMENT:
return {number:state.number+ action.count}
}
return state;
}
export default counter;
复制代码
用来合并多个reducerredux
function combineReducers(reducers){
return function(state={},action){
let obj = {};
for (let key in reducers) {
<!--第一次进来注意state[key]为undefined-->
obj[key] = reducers[key](state[key], action);
}
return obj
}
}
export default combineReducers({
counter: counter,
todo
});
复制代码
action就是一个包括type和payload属性的对象数组
export default {
add(val){
return {type:Types.INCREMENT,count:val}
}
}
复制代码
将action包装成自动dispatchbash
let bindActionCreators = (actions,dispatch) => {
let obj = {}
for(let key in actions){
obj[key] = (...args) => dispatch(actions[key](...args))
}
return obj;
}
复制代码
用来链接react和redux的ide
ReactDOM.render(<Provider store={store}>
<>
<Counter></Counter>
</>
</Provider>,window.root);
复制代码
import React,{Component} from 'react';
import Context from './context';
// Provider 主要是提供store使用的
export default class Provider extends Component{
render(){
return (<Context.Provider value={{ store: this.props.store}}>
{this.props.children}
</Context.Provider>)
}
}
复制代码
第一次执行传递两个参数mapStateToProps和mapDispatchToProps,两个都是一个函数分别传递state和dispatch参数,返回对象。函数
let mapStateToProps = (state) => { // store.getState()
return {
number: state.counter.number,
}
};
let mapDispatchToProps = (dispatch) => { // store.dipspatch
return {
add: (n) => dispatch(actions.add(n))
}
}
//若是connect 第一次执行的函数 ,若是第二个参数是对象类型 会自动内部调用bindActionCreator来实现
export default connect((state)=>state.counter,actions)(Counter)
复制代码
context API + 高阶组件ui
import React from 'react';
import Context from './context';
import { bindActionCreators} from 'redux';
let connect = (mapStateToProps, mapDipsatchToProps)=> (Component)=>{
return ()=>{
class Proxy extends React.Component{
state = mapStateToProps(this.props.store.getState());
componentDidMount(){
this.unsub = this.props.store.subscribe(()=>{
this.setState(mapStateToProps(this.props.store.getState()))
})
}
componentWillUnmount(){
this.unsub();
}
render(){
let mapDispatch;
if (typeof mapDipsatchToProps === 'object'){ //若是第二个参数传递的是一个对象,把对象直接进行包装便可
mapDispatch = bindActionCreators(mapDipsatchToProps,this.props.store.dispatch);
}else{
mapDispatch = mapDipsatchToProps(this.props.store.dispatch);
}
return <Component {...this.state} {...mapDispatch}></Component>
}
}
return <Context.Consumer>
{({store})=>{
// 将状态 和dispatch 拿到执行函数 把结果对象传递给本来的component渲染
return <Proxy store={store}></Proxy>
}}
</Context.Consumer>
}
}
export default connect;
复制代码