• React之Redux


      本文简单的说下redux。

      首先这有张网页,里面有文字和内容。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>ReactDemo</title>
    </head>
    <body>
        <div id="title"></div>
        <div id="content"></div>
        <div id="root"></div>
    </body>
    </html>

      现在让这个网页通过状态来显示标题和内容。

    let state = {
        title:{
            color:'red',
            text:'标题'
        },
        content:{
            color:'blue',
            text:'内容'
        }
    }
    
    function renderTitle(){
        let title = document.querySelector('#title');
        title.style.background = state.title.color;
        title.innerHTML = state.title.text;
    }
    
    function renderContent(){
        let content = document.querySelector('#content');
        content.style.background = state.content.color;
        content.innerHTML = state.content.text;
    }
    
    //渲染的方法
    function render(){
        renderTitle();
        renderContent();
    }
    
    render();

      这有个问题,首先状态不能是全局的,也不应该哪个方法都可以直接更改,这样做很危险,所以需要提供一个更改状态的方法,修改这状态的时候提供一个对象带有type类型的dispath来修改状态。

      

    //先定义好需要干那些事情(常量)宏
    const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
    const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
    
    let state = {
        title:{
            color:'red',
            text:'标题'
        },
        content:{
            color:'blue',
            text:'内容'
        }
    }
    //派发时一个将修改的动作提交过来
    //参数{type:'',载荷}
    function dispatch(action){    //派发的方法,这里要更改的状态
        switch(action.type){
            case CHANGE_TITLE_COLOR: 
                state.title.color = action.color;
                break;
            case CHANGE_CONTENT_TEXT :
                state.content.text = action.text;
                break;
            default:
                break;
        }
    }
    
    
    function renderTitle(){
        let title = document.querySelector('#title');
        title.style.background = state.title.color;
        title.innerHTML = state.title.text;
    }
    
    function renderContent(){
        let content = document.querySelector('#content');
        content.style.background = state.content.color;
        content.innerHTML = state.content.text;
    }
    
    
    
    
    //渲染的方法
    function render(){
        renderTitle();
        renderContent();
    }
    
    render();
    dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
    render();

      但是这么写state还是能被外人调到,所以就有了Redux里面的store。

      

    //先定义好需要干那些事情(常量)宏
    const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
    const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
    
    function createStore(){
        
        let state = {
            title:{
                color:'red',
                text:'标题'
            },
            content:{
                color:'blue',
                text:'内容'
            }
        }
    
        let getState = () => state;
        
        //派发时一个将修改的动作提交过来
        //参数{type:'',载荷}
        function dispatch(action){    //派发的方法,这里要更改的状态
            switch(action.type){
                case CHANGE_TITLE_COLOR: 
                    state.title.color = action.color;
                    break;
                case CHANGE_CONTENT_TEXT :
                    state.content.text = action.text;
                    break;
                default:
                    break;
            }
        }
        //将方法暴露给外面使用
        return {dispatch,getState}
    }
    
    
    let store = createStore();
    
    function renderTitle(){
        let title = document.querySelector('#title');
        title.style.background = store.getState().title.color;
        title.innerHTML = store.getState().title.text;
    }
    
    function renderContent(){
        let content = document.querySelector('#content');
        content.style.background = store.getState().content.color;
        content.innerHTML = store.getState().content.text;
    }
    
    
    
    
    //渲染的方法
    function render(){
        renderTitle();
        renderContent();
    }
    
    render();
    store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
    render();

       dispath写到库里面去多个开发者添加多次还是很恶心的,所以改改代码,将定义状态和规则的部分抽离到外面去。抽离的状态叫initState,抽离的规则叫reducer(也就是所谓的管理员)。

    //先定义好需要干那些事情(常量)宏
    const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
    const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
    
    let initState = {
        title:{
            color:'red',
            text:'标题'
        },
        content:{
            color:'blue',
            text:'内容'
        }
    }
    
    //需要两个参数 老的状态和新传递的动作算出新的状态
    //如果想获取默认状态就是调用reducer让每一个规则都不匹配将默认值返回
    function reducer(state=initState,action){
        //reducer是一个纯函数,每次需要返回一个新的状态
        switch(action.type){
            case CHANGE_TITLE_COLOR: 
                return {...state,title:{...state.title,color:action.color}};
            case CHANGE_CONTENT_TEXT :
                return {...state,content:{...state.content,text:action.text}};
            default:
    
                return state;
        }
    }
    
    function createStore(reducer){
        
        let state 
    
        let getState = () => state;
        
        //派发时一个将修改的动作提交过来
        //参数{type:'',载荷}
        function dispatch(action){    //派发的方法,这里要更改的状态
            state = reducer(state,action);
        }
        dispatch({})
        //将方法暴露给外面使用
        return {dispatch,getState}
    }
    
    
    let store = createStore();
    
    function renderTitle(){
        let title = document.querySelector('#title');
        title.style.background = store.getState().title.color;
        title.innerHTML = store.getState().title.text;
    }
    
    function renderContent(){
        let content = document.querySelector('#content');
        content.style.background = store.getState().content.color;
        content.innerHTML = store.getState().content.text;
    }
    
    
    
    
    //渲染的方法
    function render(){
        renderTitle();
        renderContent();
    }
    
    render();
    store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
    render();

      我们发现一个问题,每次dispath之后都得render一下,ok那么我们就整下,其实就是一个发布订阅,每次dispath时都调用订阅号的方法。

    //先定义好需要干那些事情(常量)宏
    const CHANGE_TITLE_COLOR = 'CHANGE_TITLE_COLOR';
    const CHANGE_CONTENT_TEXT = 'CHANGE_CONTENT_TEXT';
    
    let initState = {
        title:{
            color:'red',
            text:'标题'
        },
        content:{
            color:'blue',
            text:'内容'
        }
    }
    
    //需要两个参数 老的状态和新传递的动作算出新的状态
    //如果想获取默认状态就是调用reducer让每一个规则都不匹配将默认值返回
    function reducer(state=initState,action){
        //reducer是一个纯函数,每次需要返回一个新的状态
        switch(action.type){
            case CHANGE_TITLE_COLOR: 
                return {...state,title:{...state.title,color:action.color}};
            case CHANGE_CONTENT_TEXT :
                return {...state,content:{...state.content,text:action.text}};
            default:
                return state;
        }
    }
    
    function createStore(reducer){
        
        let state ;
        let listeners = [];
        let subscirbe = (listener)=>{   //订阅
            listeners.push(listener);
            return ()=>{
                //再次调用时移除监听函数。
                listeners = listener.filter(fn => fn !== listener);
            }
        }
    
        let getState = () => state;
        
        //派发时一个将修改的动作提交过来
        //参数{type:'',载荷}
        function dispatch(action){    //派发的方法,这里要更改的状态
            state = reducer(state,action);
            listeners.forEach(listener=>listener());
        }
        dispatch({})
        //将方法暴露给外面使用
        return {dispatch,getState,subscirbe}
    }
    
    
    let store = createStore();
    
    function renderTitle(){
        let title = document.querySelector('#title');
        title.style.background = store.getState().title.color;
        title.innerHTML = store.getState().title.text;
    }
    
    function renderContent(){
        let content = document.querySelector('#content');
        content.style.background = store.getState().content.color;
        content.innerHTML = store.getState().content.text;
    }
    
    //渲染的方法
    function render(){
        renderTitle();
        renderContent();
    }
    render();
    //订阅
    store.subscirbe(render)
    setTimeout(() => {
        store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
    }, 2000)
    
    //取消订阅
    // let unsub = store.subscirbe(render)
    // setTimeout(() => {
    //     unsub();
    //     store.dispatch({type:CHANGE_CONTENT_TEXT,text:'随便改的'});
    // }, 2000);
  • 相关阅读:
    ES ElasticSearch 7.x 下动态扩大索引的shard数量
    Java框架Spring Boot & 服务治理框架Dubbo & 应用容器引擎Docker 实现微服务发布
    谈一下Docker与Kubernetes集群的日志和日志管理-转载
    Elasticsearch优化 & filebeat配置文件优化 & logstash格式配置 & grok实践
    Nginx错误日志(error_log)配置及信息详解
    赵总的运维体系专栏学习的总结
    APP或者前端通过识别用户代理详细信息和浏览器数据进行安全防御
    Kubernetes使用Eedpoints连接外部服务端口
    CDN域名解析问题
    Istio 实践 之 Circuit breakers 断路器 (请求熔断)
  • 原文地址:https://www.cnblogs.com/qiaohong/p/9824215.html
Copyright © 2020-2023  润新知