Redux基本解析及其使用和React-Redux

一.Redux 解析

1).统一数据管理
	将所需的数据提取到state中统一进行管理。当渲染后我们希望更改状态,封装更改状态的方法(dispatch)
2).实现dispatch
	不要直接更改状态而是使用dispatch方法进行状态的更改,派发一个带有type的属性来进行状态的更改,但是依然无法阻止用户更改状态.
3).createStore的实现
	将状态放到了createStore函数中,目的是隔离作用域,并且再内部返回深度克隆的对象,这样用户无法再通过外界更改状态。但是状态应该由我们自身来控制,应该是外界传入的,所以要将状态拿出createStore。并且判断的逻辑也应该由我们自己来编写
4).reducer的实现
	我们已将需要自己处理的逻辑提取出来,但是我们每次dispatch时都需要自己触发视图的更新,我们希望采用发布订阅来实现。
5).订阅函数
	我们redux中常用的方法已经封装完成我们将封装好的逻辑抽离成redux.js

二.Redux深入

2.1 redux文件拆分
	store
	    │  action-types.js
	    │  index.js
	    │
	    ├─actions
	    │      counter.js
	    │
	    └─reducer
	            counter.js
	            
	   action-types用来存放需要的常量
	   counter中存放reducer的逻辑
	   store中的index文件用来创建store	
	   action文件夹中的counter,用来生成对应组件的action对象
2.2 实现多个counter
在redux中只能拥有一个store所以我们需要将多个状态进行合并,状态是通过reducer返回的,所以我们可以将多个reducer进行合并达到合并状态的目的。
		│  index.js
		│  redux.js
		│
		├─components
		│      counter1.js
		│      counter2.js
		│
		└─store
		    │  action-types.js
		    │  index.js
		    │
		    ├─actions
		    │      counter1.js
		    │      counter2.js
		    │
		    └─reducer
		            counter1.js
		            counter2.js
		            index.js
	action-types新增counter2处理的常量
	对应的counter2中的action也进行更改

三. React-Redux

1.为什么需要高阶组件
	从本地存储中获取数据放到输入框内的逻辑应该就是公用逻辑。这时我们就要使用高阶组件,也就是将组件在原有的基础上进行包装。
2.实现高阶组件
	我们将公共的逻辑拿到外层组件,处理好后以属性的方式传递给原本的组件,为此高阶组件就是一个 React 组件包裹着另外一个 React 组件
3.context的用法
	react是单向数据流,我们想传递数据需要一层层向下传递,数据传递变得非常麻烦,我们可以用context实现数据的交互
		1) 父 childContextTypes getChildContext函数
		2) 子 contextTypes
import React from 'react';
import ReactDOM from 'react-dom';
import Counter from "./components/Counter";
import store from './store/index';
import {Provider} from 'react-redux';
ReactDOM.render(
  <Provider store={store}>
    <Counter/>
  </Provider>,window.root);
// counter组件
class Counter extends React.Component {
  render(){
    return <div>
      数量:{this.props.number}
      <button onClick={()=>{this.props.add(1)}}>+</button>
      <button  onClick={()=>{this.props.minus(1)}}>-</button>
      </div>
  }
}
export default connect(state=>({...state}),dispatch=>({
  add:(amount)=>{dispatch(actions.add(amount))},
  minus:(amount)=>{dispatch(actions.minus(amount))}
}))(Counter)

四.MiddleWare的使用

1.logger中间件
	在控制台查看更改前后的状态
2.实现redux-thunk中间件
	实现派发异步动作,actionCreator可以返回函数,可以把dispatch的权限交给此函数
3.实现redux-promise中间件
	返回一个实例 ,支持异步请求  看resolve  reject情况

五. Redux 源码仿写

 	 <div id="title"></div>
    <div id="content"></div>
  // state  getState  dispatch   subscribe
        // subscribe : 订阅;可以订阅一些方法,当执行完dispatch之后,会把订阅的方法执行
        const CHANGE_TITLE_TEXT = "CHANGE_TITLE_TEXT";
        const CHANGE_CONTENT_COLOR = "CHANGE_CONTENT_COLOR";
        function createStore(reducer) {
            let state;
            let listeners = [];
            let getState = () => JSON.parse(JSON.stringify(state));
            function dispatch(action) {
                state = reducer(state, action);
                // 调用dispatch就会发布listener中的方法;
                listeners.forEach(item => {
                    if (typeof item === "function") {
                        item();
                    }
                })
            }
            dispatch({});
            function subscribe(fn) {
                listeners.push(fn);
                // 返回一个取消订阅的方法,当返回值执行时,取消对应的订阅
                return () => {
                    listeners = listeners.filter(item => item !== fn);
                }
            }
            return {
                getState,
                dispatch,
                subscribe
            }
        }
        let initState = {
            title: { color: "red", text: "xxWOxx" },
            content: { color: "yellow", text: "qqNIqq" }
        };

        function reducer(state = initState, action) {// 形参
            switch (action.type) {
                case CHANGE_TITLE_TEXT:
                    return { ...state, title: { ...state.title, text: action.text } };
                case CHANGE_CONTENT_COLOR:
                    return { ...state, content: { ...state.content, color: action.color } }
            }
            return state;
        }
        let store = createStore(reducer);

        function renderTitle() {
            let title = document.getElementById("title");
            title.innerHTML = store.getState().title.text;
            title.style.color = store.getState().title.color;
        }
        function renderContent() {
            let content = document.getElementById("content");
            content.innerHTML = store.getState().content.text;
            content.style.color = store.getState().content.color;
        }
        function renderApp() {
            renderTitle();
            renderContent();
        }
        renderApp();
        setTimeout(function () {
            store.dispatch({ type: CHANGE_TITLE_TEXT, text: "好好学习" });
            store.dispatch({ type: CHANGE_CONTENT_COLOR, color: "blue" })
            // renderApp();
        }, 2000)
        // 订阅renderApp这个方法,然后执行dispatch,就会发布这个方法;
        // let f = store.subscribe(renderApp);
        // f();// 取消订阅
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值