飞道的博客

react redux使用

226人阅读  评论(0)

一、redux基本使用

创建项目

没有环境先安装:
$ npm install -g create-react-app

创建项目

create-react-app react-redux-ant

安装 redux

yarn add redux --save

在src目录下新建目录store和index.js和reducer.js

新建目录reducers,和reducer.js

reducer.js中定义数据


//reducer.js
const  defaultState  = {
   
    number:0,
    userInfo:{
   
        name:'wxq'
    }
}


export default (state = defaultState,action)=> {
   
    return state
}

store/store.js引入createStore方法

import {
   createStore} from 'redux'
import reducer from "../reducers/reducer";


const store  = createStore(reducer)//创建仓库

export  default  store //暴露store



入口文件使用store,其他组件可以拿到数据

import store from "./store";

ReactDOM.render(
    <App store= {
   store} />,
  document.getElementById('root')
);

组件使用

props.store.getState()//获取数据
import React from 'react'

export  default  function Index(props) {
   
    console.log("props",props)
    console.log("props",props.store.getState())
    const {
    number } = props.store.getState()
    return <div>
        <h1>count组件</h1>
        <h1>count:{
   number}</h1>
    </div>
}

store值的修改

   const add = ()=>{
   
        props.store.dispatch({
   type:'ADD',data:1})//通过dispatch函数触发reducer的action
    }
import React from 'react'
import store from "../../store";

export  default  function Index(props) {
   
    console.log("props",props)
    console.log("props",props.store.getState())
    const {
    number } =props. store.getState()
    const add = ()=>{
   
        props.store.dispatch({
   type:'ADD',data:1})
    }
    return <div>
        <h1>count组件</h1>
        <h1>count:{
   number}</h1>
        <button onClick={
   add}>+1</button>
        <button>-1</button>
    </div>
}


//reducer.js
const  defaultState  = {
   
    number:0,
    userInfo:{
   
        name:'wxq'
    }
}


export default (state = defaultState,action)=> {
   

    switch (action.type) {
   
        case 'ADD':
            console.log(state)
            return {
   ...state,number:state.number += action.data}
        default :
            return state
    }
    return state
}

数据修改完成,进行数据个更新,通过store的订阅功能进行更新,也就是组件需要重新赋值一次数据,利用store中subscribe()函数进行发布订阅

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import store from "./store";
ReactDOM.render(
    <App store= {
   store} />,
  document.getElementById('root')
);
store.subscribe(()=>{
   
    ReactDOM.render(
    <App store= {
   store} />,
    document.getElementById('root')
);
})


// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// reportWebVitals();

二、 redux使用流程进阶(根据数据类型划分模块)

在项目中根据不同类型数据进行模块划分,可以使代码清晰明了,方便维护

在reducers文件夹建一个reducers.js来管理分片的reducers

//建立一个总的reducers来管理分片的reducers
//管理分片的reducers我们需要借助redux中的一个工具combineReducers


//reducers.js
//建立一个总的reducers来管理分片的reducers
//管理分片的reducers我们需要借助redux中的一个工具combineReducers

import {
    combineReducers }  from 'redux';
import counter from './counter/index'


const reducers = combineReducers( {
   
    // 其中为分片式的reducers
    counter
})

export default reducers;

三、 redux使用过程代码优化

1.我们需要使用一个工具(react-redux)对redux进行代码优化

2.需要在组件的最外层套上Provider组件,并为其传入store

3.利用connect将需要使用store相关api的组件变成容器组件嵌套UI组件的模式

4.connect方法的返回值是一个函数,这个函数接收到UI组件之后会返回一个容器组件,容器内部已经嵌套了UI组件

5.Provider组件会利用context上下文将自己属性中store传递给自己的子级组件,而容器组件会取得context上面的store相关的api

6.我们可以在connect函数中传入mapStateToProps/mapDispatchToProps参数来掌控容器组件给UI组件传递属性的过程

7.mapStateToProps的作用:

  • 将store中的state传递到UI组件的属性上
  • 值为一个函数,接收到的就是store中的state
  • 返回值是什么,UI组件的属性上就有什么
  • 并且,因为容器组件中已经做好了store.subscribe的处理,所以一旦store中的状态变化,
    容器组件就马上能得知,就会重新给UI组件传入新的数据

8.mapDispatchToProps的作用:

  • 可以将能使用到dispatch的一些方法传递到UI组件上
  • 值为一个函数,接收到的就是store中的dispatch
  • 返回什么,UI组件的属性上就有什么

优化流程

1、安装react-redux
yarn add react-redux

2、首先我们在最大的组件外添加一个标签,并将store模块作为属性值引入

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import store from "./store";
import {
   Provider} from 'react-redux'

ReactDOM.render(
< Provider
store = {
   store} >
    < App />
    < /Provider>
    ,
    document.getElementById('root')
)
;
// store.subscribe(()=>{
   
//     ReactDOM.render(
//     <App store= {store} />,
//     document.getElementById('root')
// );
// })


// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// reportWebVitals();

3、 组件内

export default connect( state => state)(Index)

import React from 'react'
import  {
    connect } from 'react-redux'
//从redux中引入一个方法用于将actionCreators中的方法进行绑定
import {
    bindActionCreators } from 'redux'
import  actionCreators from  '../../reducers/counter/actionCreators'
const Index =  function Index(props) {
   
    console.log("props",props)
    const {
    number } =props.counter;
    const add = ()=>{
   
     const  dd =   props.add()
        console.log(dd)

    }
    return <div>
        <h1>count组件</h1>
        <h1>count:{
   number}</h1>
        <button onClick={
   add}>+1</button>
        <button>-1</button>
    </div>
}

export  default  connect( state => state,dispatch => bindActionCreators(actionCreators,dispatch) )(Index)

//actionCreators.js代码
import * as type from './type';
const actionCreators={
   

    add(){
   
        //创建动作
        const action = {
   
            type:type.ADD,
        }
        return action
    }
}

export default actionCreators;

初步修改之后,可以看到props中打印是这样的,依然可以正常使用

5、redux中数据交互如何解决

我们使用上述方法管理数据很简单

但是有一点小问题,如果我们有了异步操作,比如我们会先执行一个ajax调用之后再去更改状态的话,这个异步动作,没有地方放了

我们不能把异步动作放到组件中,因为UI组件只负责使用数据,如果有其他的异步代码,让UI组件组件不纯粹

理论上来说放到actionCreator的方法中最合适,但是,因为actionCreator目前只是专注于创建action和返回action,无法放入异步操作;
针对这个问题我们可以用redux的中间件redux-thunk来解决;

1.安装redux-thunk

yarn add redux-thunk

2.在创建store的时候使用中间件

import {
   createStore,applyMiddleware } from 'redux'
import reducer from "../reducers/reducers";

import thunk from 'redux-thunk'
const store  = createStore(reducer,applyMiddleware(thunk))//创建仓库

export  default  store //暴露store


)

3这个时候,actionCreator的方法就可以返回一个能接收到dispatch的一个函数,我们可以在这个函数中进行异步操作之后,将actionCreator创建好的action给发送

//actionCreators.js代码
import * as type from './type';
const actionCreators={
   

    add(){
   
        //创建动作
        const action = {
   
            type:type.ADD,
        }
        return action
    },
    getInfo () {
   //异步数据的请求方式
        //进行数据交互
        /* 
          actionCreators中用于数据交互的方法必须要有返回值,返回值是一个函数,函数接收一个参数,这个参数就是dispatch
        */
        return dispatch  => {
   
            fetch('/data.json')
                .then(res => res.json())
                .then(data => {
   
                    // 动作的创建
                    const action = {
   
                        type:type.GET_INFO,
                        payload:data,
                    }
                    // 动作的发送
                    dispatch (action)
                })

        }
    }

}

export default actionCreators;

进阶umi和dva实战

下一篇文章:umi和dva实战


转载:https://blog.csdn.net/waillyer/article/details/116425833
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场