redux状态管理和react-redux的结合使用

原文:  https://www.cnblogs.com/kelly2017/p/8034251.html

一:调试

注意: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处理发送请求异步。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

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就会重新渲染页面

1

2

3

4

5

6

7

8

9

10

11

12

13

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:'加'});

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

//通过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以及相应的函数

1

<span style="font-size: 18px; font-family: 楷体">const store=this.props.store</span>

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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中

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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}),<br>    //第一个参数,state里的属性放到props里面

    {addFn,minusFn,addAsyn}<br>    //方法放到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.直接引入合并之后的就可以

1

2

3

4

5

6

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的初始状态。

  

猜你喜欢

转载自blog.csdn.net/qq_34629352/article/details/84325056