持续创作,加速成长!这是我参与「掘金日新计划 · 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可以看到我们传入的属性与方法。
、
三.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>
);
};