React-redux的使用及数据持久化、高阶组件的构建与应用

865 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

React-redux概念

我们知道Redux是目前非常流行的状态管理工具,在实际开发中,常常与React绑定使用,React-redux就是Redux官方的React绑定库,它提供Provider全局函数,使我们在全局能够更为方便的获取store中的状态,同时使用高阶组件connect将store中的state属性以及action方法转化为props注入组件,使我们能够与store更好的关联,从而言之,React-redux是Redux在React中的简化使用版本,能够更好的帮助我们进行状态管理。本文将从React-redux的基本使用、connect高阶组件的实现原理及复写、数据持久化三方面进行讲解。

使用方法

1.APP.js

react-redux中引入provider,包含store。React-redux中提供Provider全局函数,它包含整个路由对象内容,利用Provider将store中的state自上而下传入组件中,但此时store中的state与组件并无联系,需要使用connectmapStateToProps将state属性转化为组件props。

import React, { Component } from 'react'
import Content from './react-redux/content'
import { Provider } from 'react-redux'
import store from './redux/store'
export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Content />
      </Provider>
    )
  }
}

2.组件内

使用高阶组件 connect,connect有两个参数,第一参数为注入子组件的属性,第二个属性为执行的方法。通过mapStateToProps将store中的state转为组件的props属性,通过mapDiapatchToProps将派发方法内容转化为props属性对象。

import React, { Component } from 'react'
import { connect } from 'react-redux'
class Content extends Component {
  render() {
    return (
      <div>
          <span>{this.props.name}</span>
        <div onClick={()=>{this.handleChange()}}>修改name</div>
      </div>
    )
  }
   handleChange=()=>{
      this.props.changeName('修改后名字')
  }
}
const mapStateToProps=(state)=>{
    return {
        name:state.name
    }
}
const mapDiapatchToProps={
    changeName(name){
        return {
            type:"change",
            payload:name
        }
    }
}
export default connect(mapStateToProps,mapDiapatchToProps)(Content)

3.store内

store内与redux使用方式一致,通过reducer对组件视图层dispatch的action进行检测,从而对数据进行不同的操作。

import {createStore} from 'redux'   
const reducer=(prevState={},action,payload)=>{
    const newdata={...prevState}
    switch (action.type){
        case 'change':
            newdata.name=action.payload
            return newdata
        default:
            return newdata
    }
}
const state={
    name:'test'
}
const store=createStore(reducer,state)
export default store

4.react-redux组件原理

该组件提供的Provider与connect实际上是 HOC与context通信在react-redux底层的应用 (1)connect是HOC,高阶组件,可以将参数注入组件。 (2)Provider组件可以让容器组件拿到state,使用了context。

二.仿照connect进行高阶组件构建与应用

HOC不仅仅是一个方法,确切说是一个组件工厂,获取低阶组件,生成高阶组件
(1)代码复用,代码模块化
(2)增删改props
(3)渲染劫持
手写一个仿connet的高阶组件

我们需要实现将属性、方法注入参数,并且要维持原有组件参数
我们将mapStateToProps、mapDiapatchToProps传入我们的高阶组件中,使用value承接执行mapStateToProps方法返回的的属性值,第一个return回调函数中可以接收我们传来的组件,第二个回调函数中,我们可以接收原有组件的参数,最后将value、action、props展开注入传入组件中并返回,就实现了一个仿connect的简单版高阶组件。

import React, { Component } from 'react'
class Info extends Component {
     componentDidMount(){
         console.log(this.props)
     }
  render() {
    return (
      <div>info</div>
    )
  }
}
function HocConnect(cb,action){
    let value=cb()
    return (MyComponent)=>{
        return (props)=>{
            return <div>
            <MyComponent {...value} {...action} {...props}>
            </MyComponent>
        </div> 
        }
    }
}
const mapStateToProps=()=>{
    return {
        name:'test'
    }
}
const mapDiapatchToProps={
    changeName(name){
        return {
            type:"change",
            payload:name
        }
    }
}
export default HocConnect(mapStateToProps,mapDiapatchToProps)(Info)

在组件中打印props可以看到我们传入的属性与方法。捕获.PNG

三.redux数据持久化

开发中store状态再刷新页面后一般会进行重置,但有些时候我们希望能够保存状态,这个时候就用到了redux-persist进行数据的持久化,该插件其实利用localStorage进行状态持久化。使用persistConfig进行参数配置,开发文档:redux-persist(https://www.npmjs.com/package/redux-persist) store.js

// configureStore.js

import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
 
import rootReducer from './reducers'
 
const persistConfig = {
  key'root', // 存储到localstorage的key名
  storage,
  whitelist: ['navigation'// only navigation will be persisted 要存储的数据白名单
}
 
const persistedReducer = persistReducer(persistConfig, rootReducer)
 
export default () => {
  let store = createStore(persistedReducer)
  let persistor = persistStore(store)
  return { store, persistor }
}

APP.js

import { PersistGate } from 'redux-persist/integration/react'
 
// ... normal setup, create store and persistor, import components etc.
 
const App = () => {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <RootComponent />
      </PersistGate>
    </Provider>
  );
};