redux 练习8 redux-persist实现redux数据持久化

redux-persist 必须要与react-redux配合使用,才能实现数据持久化

note: 先将store和中间件都创建好,然后直接按照文档使用redux-persisit就好

App.js

import { HashRouter as Router, Switch, Route } from 'react-router-dom'

import Layout from './view/Layout'
import Login from './view/Login'

// 通过redux创建的store
import { store, persistor } from './store'

import { Provider } from 'react-redux'

import { PersistGate } from 'redux-persist/integration/react'

export default function App() {
  return (
    // 通过react-redux的Provider向全局提供一个store
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <Router>
          <Switch>
            <Route path="/login" component={Login} />
            <Route path="/" component={Layout} />
          </Switch>
        </Router>
      </PersistGate>
    </Provider>
  )
}

src/store/index.js 这里先把store的逻辑写清楚,再照着redux-persist的文档把持久化配置加进去就好了

import { createStore, combineReducers, applyMiddleware } from 'redux'

import reactPromise from 'redux-promise'

import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' 

const initState1 = {
  login: false,
}

const initState2 = {
  username: ''
}

const reducer1 = (state = initState1, action) => {
  const newState = {...state}
  switch (action.type) {
    case 'login':
      newState.login = action.login;
      return newState
    default:
      return state
  }
}

const reducer2 = (state = initState2, action) => {
  const newState = {...state}
  switch (action.type) {
    case 'username':
      newState.username = action.username
      return newState
    default:
      return state
  }
}

const persistConfig = {
  key: 'userinfo',
  storage,
}

const reducers = combineReducers({logininfo: reducer1, userinfo: reducer2})

const persistedReducer = persistReducer(persistConfig, reducers)

const store = createStore(persistedReducer, applyMiddleware(reactPromise))

const persistor  = persistStore(store)

export { store, persistor }

src/view/login.js

import { useState } from 'react'
import { connect } from 'react-redux'

function Login(props) {
  const [username, setUsername] = useState('')
  const [password, setPs] = useState('')

  const changeUsername = (ev) => {
    setUsername(ev.target.value)
  }

  const changePs = (ev) => {
    setPs(ev.target.value)
  }

  const loginHandle = () => {
    if (!(username && password)) return alert('用户名或者密码不能为空')
    props.history.push('/')
    props.login({
      type: 'login',
      login: true
    })
    props.setName({
      type: 'username',
      username
    })
  }

  return (
    <div>
      <input value={username} onChange={ (ev) => changeUsername(ev) } placeholder='请输入用户名' />
      <input type="password" value={password} onChange={ (ev) => changePs(ev) } placeholder='请输入密码' />
      <button onClick={ loginHandle }>登 录</button>
    </div>
  )
}

const mapDispatchToProps = {
  login(obj) {
    return {
      ...obj
    }
  },
  setName(nameinfo) {
    return {
      ...nameinfo
    }
  }
}

export default connect(null, mapDispatchToProps)(Login)

src/view/Layout.js (里面还有一个/list 和 /detail 页面就不展示了)

import List from './Layout/List'
import Detail from './Layout/Detail'
import { Switch, Route, Redirect } from 'react-router-dom'

import { connect } from 'react-redux'

const routesConfig = [
  {
    path: '/list',
    component: List
  },
  {
    path: '/Detail/:id',
    component: Detail
  }
]

function Layout(props) {

  const { isLogin, username } = props;

  return (
    <>
      <h4>用户名:{username}</h4>
      <button onClick={() => {
        // 第一个参数是设置login为false,第二个参数是把username置为空
        // 组件中直接调用映射的函数即可
        // props.clearLogin(false)
        // props.clearUsername('')
        props.history.push('/login')
        localStorage.clear()
      }}>退出</button>
      <Switch>  
        {
          routesConfig.map(item => isLogin ? <Route key={item.path} {...item} /> : <Redirect key={item.path} to="/login" />)
        }
        { isLogin && <Redirect from="/" to={routesConfig[0].path} /> }
      </Switch>
    </>
  )
}

// 映射store中的state到组件的props
const mapStateToProps = (state) => ({
  isLogin: state.logininfo.login,
  username: state.userinfo.username
})

// 映射dispatch到组件的props
const mapDispatchToProps = {
  clearLogin(loginstatus) {
    return {
      type: 'login',
      login: loginstatus
    }
  },
  clearUsername(username) {
    return {
      type: 'username',
      username
    }
  }
}
// connect是一个高阶函数介绍两个参数,第一个是一个函数,第二个是一个对象
export default connect(mapStateToProps, mapDispatchToProps)(Layout)
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容