zoukankan      html  css  js  c++  java
  • redux状态管理和react-redux的结合使用

    一:调试

    注意:Redux调试工具。谷歌中搜redux同理react

    新建store的时候判断window.devToolsExtension
    使用compose(组合函数)结合thunk插件和window.devToolsExtens

    二:Redux

    Redux 是 JavaScript 状态容器,专注于状态管理的库

    整体来说是单一状态。就是指的是单向的数据流

    应用中所有的 state 都储存在 store 中。 惟一改变 state 的办法是dispatch触发 action,为了描述 action 如何改变 state ,需要编写 reducer。

    redux中最重要的几个:store     state     action    reducer

    首先安装redux   安装:http://www.cnblogs.com/kelly2017/p/7930681.html

    package.json中有

    react-redux把状态映射到子组件 分发reducer

    redux  创建reducer action store等   

    react-thunk  thunk处理发送请求异步。

    import { createStore } from 'redux';     
    //新建一个store
    //通过reducer来建立,是个形式为 (state, action) => state 的纯函数。
    //reducer描述了 action 如何把老的状态state和action 生成新的状态state
    // action有type
    function  couter(state=0, action) {
        switch (action.type){
            case '加':
                return state+1
            case '减':
                return state-1
            default:
            return 1
        }
    }
    const store=createStore( couter ) 
    //1: 创建 Redux store 来存放应用的状态(根据reducer来创建)
    // store  应用中所有的 state 都储存在一个单一的 store 中。 
    const init=store.getState()
    //store.getState()随时获取最新的状态
    console.log(init)
    //派发事件  
    //需要状态变更的时候 store.dispatch(action)来提交状态变更
    //改变内部 state 惟一方法是 dispatch 一个 action。
    store.dispatch({type:'加'})
    //console.log(store.getState())
    store.dispatch({type:'加'})
    //console.log(store.getState())
    store.dispatch({type:'减'})
    //console.log(store.getState)
    function listener() {
        const current=store.getState()
        console.log(`现在的总数是${current}`)
    }
    store.subscribe(listener)
    //subscribe 订阅事件
    //store.subscribe来监听每次state修改
    //每次dispatch都会执行listener
    

    运行结果:

    2:Redux和React

    redux和react一起结合使用的方法:

    1)
    因为改变内部 state 惟一方法是 dispatch 一个 action。
    所以把store.dispatch的方法传递给组件,使其内部可以调用修改状态
    react的修改状态从之前的setState({})变成了由store来统一管理
    2)
    store.subscribe来监听每次state修改
    每次dispatch都会执行订阅的事件
    subscribe来定义render函数,每次修改都重新渲染页面。
    3)
    react和redux的文件分离

    index.js中 创建store

    订阅subscribe只要状态改变。就重新渲染页面 render()

    const store=createStore(couter)

    新建store.以组件属性的形式。添加到component组件里

    通过subscribe订阅这个render函数,状态有变化。render就会重新渲染页面

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { createStore } from 'redux';
    import App from './App';
    import { couter,addFn,minusFn } from './index.redux';
    import registerServiceWorker from './registerServiceWorker';
    const  store=createStore(couter)
    function render() {
        ReactDOM.render(<App store={store} addFn={addFn} minusFn={minusFn}/>, document.getElementById('root'));
    }
    render()
    store.subscribe(render)
    registerServiceWorker();
    

      

    新建index.redux.js专门管理redux

    存放reducer和 dispatch的action   //store.dispatch({type:'加'});

    //通过reducer来建立。
    const ADD="加";
    const MINUS="减";
    export function  couter(state=0, action) {
        switch (action.type){
            case ADD:
                return state+1
            case MINUS:
                return state-1
            default:
                return 1
        }
    }
    //store.dispatch({type:'加'});store.dispatch({type:'减'})
    //action
    export function addFn() {
        return { type:ADD }
    }
    export function minusFn() {
        return { type:MINUS }
    }
    

     

    app.js中使用

    内部通过属性获取store以及相应的函数

    const store=this.props.store

    点击的时候要改变状态 dispatch     //addFn() 执行返回的是对象

    import React, { Component } from 'react';
    class App extends Component {
        constructor(props){
            super(props)
        }
      render() {
       const store=this.props.store
       const addFn=this.props.addFn
       const minusFn=this.props.minusFn
       const init=store.getState()
        return (
          <div className="App">
              <h1>你好吗?</h1>
              <p>现在的总数是:{init}</p>
              <button onClick={ ()=>store.dispatch( addFn() ) }>加1</button>
              <button onClick={ ()=>store.dispatch( minusFn() ) }>减1</button>
          </div>
        );
      }
    }
    export default App;
    

      

    运行结果能实现简单的通过redux管理状态:

     

     三:redux异步处理   redux-thunk

    强制清除缓存 。npm报错。code为408(不允许安装) 这时候执行  npm cache clean --force

    处理异步

    redux默认情况下只处理同步,想要处理异步,需要上面安装的redux-thunk插件
    先引入:
    import { createStore ,applyMiddleware } from 'redux';
    import thunk from 'redux-thunk'
    使用applyMiddleware在创建store的时候开启中间件
    const store=createStore(couter ,applyMiddleware(thunk))
    之前action是个对象。直接dispatch这个对象就直接修改状态。store.dispatch({type:MINUS})
    export function minusFn() {
    return { type:MINUS }
    }
    action可以返回函数,使用dispatch提交action
    addAsyn() 这个函数可以返回个函数。
    export function addAsyn() {
      return dispatch=>{
        setTimeout(()=>{
          dispatch(addFn())
         },2000)
    }
    dispatch是个参数。setTimeout结束之后手动执行dispatch

    入口:index.js

    app.js

    index.redux.js

    多向外暴露个函数

    实现效果:

    四:react和redux的结合使用     

    插件:react-redux

    不适用subscribe发布事件

    提供provider和connect两个接口链接react和redux

    index.js调整

    
    
    import React from 'react';
    import ReactDOM from 'react-dom';
    import { createStore ,applyMiddleware } from 'redux';
    import thunk from 'redux-thunk'
    import { Provider } from 'react-redux'
    import App from './App';
    import { couter } from './index.redux';
    import registerServiceWorker from './registerServiceWorker';
    const store=createStore(couter , applyMiddleware(thunk))
    ReactDOM.render(
    (<Provider store={store}>
    < App />
    </Provider>)
    , document.getElementById('root'));
    registerServiceWorker();
    
    

     

     app.js中  

    connect负责从外部获取组件需要的参数。放到props中

    import React, { Component } from 'react';
    import { connect } from 'react-redux'
    import {addFn,minusFn,addAsyn} from './index.redux'
    class App extends Component {
      render() {
       const num=this.props.num
       const addFn=this.props.addFn
       const minusFn=this.props.minusFn
       const addAsyn=this.props.addAsyn
        return (
          <div className="App">
              <h1>你好吗?</h1>
              <p> { num }</p>
              <button onClick={addFn}>加1</button>
              <button onClick={minusFn}>减1</button>
              <button onClick={addAsyn}>异步加1</button>
          </div>
        );
      }
    }
    //num  state状态 映射到属性里面
    const mapStatetoProps=(state)=>{
       return {num:state}
    }
    //num 可以通过props获取
    const actionCreators={addFn,minusFn,addAsyn}
    //addFn 自动有了dispatch的功能 onClick={addFn}
    //addFn  minusFn  minusFn会被映射到props里面
    //this.props.addFn 可以通过props获取
    App=connect(mapStatetoProps,actionCreators)(App)
    export default App;
    

      

    
    

    五:@优化

    安装插件,配置package.json介绍:http://www.cnblogs.com/kelly2017/p/7930681.html

    import { connect } from 'react-redux'
    import {addFn,minusFn,addAsyn} from './index.redux'
    //num  state状态 映射到属性里面
    // const mapStatetoProps=(state)=>{
    //     return {num:state}
    // }
    //num 可以通过props获取
    // const actionCreators={addFn,minusFn,addAsyn}
    //addFn 自动有了dispatch的功能 onClick={addFn}
    //addFn  minusFn  minusFn会被映射到props里面
    //this.props.addFn 可以通过props获取
    //App=connect(mapStatetoProps,actionCreators)(App)
    //@connect(mapStatetoProps,actionCreators)
    @connect(
        (state)=>({num:state}),
    //第一个参数,state里的属性放到props里面 {addFn,minusFn,addAsyn}
    //方法放到props里 )

      

     六:多个reducer之间的合并问题

    新建一个专门用来合并用的reducer.js 主要的合并的方法 combineReducers

    //多个reducer之间的合并  并且返回
    import {combineReducers} from 'redux'
    //redux提供的用于多个reducer合并的方法
    // 里面是个对象。罗列需要合并的reducer
    import { couter } from './index.redux'; //项目中需要的reducer
    import { auth } from './Auth.redux'; //项目中需要的reducer
    export default combineReducers({couter,auth})

     在index.js中不需要之前引入的单个的reducer.直接引入合并之后的就可以

    import reducer from './reducer'
    import Dashboard from './Dashboard'
    import registerServiceWorker from './registerServiceWorker';
    //之前就一个couter reducer 现在加了一个auth reducer
    const  store=createStore( reducer , applyMiddleware(thunk) )
    console.log(store.getState())
    

      打印结果:合并之后的两个reducer的初始状态。

      

     

     

     

     

     

     

     

     

     

     

     

     

     

     

      

     

  • 相关阅读:
    215. Kth Largest Element in an Array (have better solution )
    414. Third Maximum Number
    442. Find All Duplicates in an Array
    448. Find All Numbers Disappeared in an Array
    485. Max Consecutive Ones
    532. K-diff Pairs in an Array
    8. String to Integer (atoi)
    7. Reverse Integer
    [CTSC2012]熟悉的文章(广义后缀自动机+二分答案+单调队列优化DP)
    BZOJ 2119 股市的预测(后缀数组)
  • 原文地址:https://www.cnblogs.com/kelly2017/p/8034251.html
Copyright © 2011-2022 走看看