基于react-hooks的替代redux解决方案

背景

react hooks 已经发布好久了,相关文档已经有了大量的资源.
本文提供一个基于react-hooks的redux 替代解决方案.
PS: 没有最好的解决方案,只有最适合的解决方案.本文不完善的地方请在评论指出
项目地址 https://github.com/Tangpriest/hooks_demo
复制代码

关键字

create-react-app react-hooks
复制代码

初始化项目

初始化项目用的是create-react-app脚手架
为何不用webpack本身构建? 由于懒 ......
实际上是由于这不是本文讲解的重点
复制代码
运行如下语句其中之一初始化项目
复制代码
用npx的话 (也是官方推荐的作法)
npx create-react-app demo
用npm
npm init react-app my-app
用yarn
yarn create react-app my-app
复制代码
而后你大概获得了如下的项目结构
复制代码
demo
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    └── serviceWorker.js
复制代码
稍微修改下项目目录,把src下面全部文件都删掉了,只留下index.js ,编辑index.js
复制代码
import React from 'react'
import ReactDOM from 'react-dom'

const App = function (){
  const [title,setTitle] = React.useState('react-redux')
  return (
    <div onClick={()=>{setTitle('react-hooks')}}>{title}</div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码
命令行 npm start 或者 yarn start 至此~咱们的项目初始化结束
复制代码

引入hooks

在src下面新建文件 store.js
首先用react提供的createContext 建立一个Context
export const GlobalContext = React.createContext({})

而后构造一个最外层的GlobalProvider组件用来包裹子组件
用useState函数定义了store里面的appName字段以及修改该字段的方法,
并在value里面传递给后面的子组件

完整的store.js在下面 其实这一步就对应了redux中的createStore和reducer
复制代码
import React from 'react'

export const GlobalContext = React.createContext({})

export function GlobalProvider(props) {
  const [appName, setAppName] = React.useState('react-redux')
  return (
    <GlobalContext.Provider
      value={{
        appName,
        setAppName
      }}
    >
      {props.children}
    </GlobalContext.Provider>
  )
}

复制代码
修改index.js 用store.js里面提供的<GlobalProvider>组件包裹<App>组件
至此 改造已经完成
!!!惊不惊喜 意不意外 没有react-redux 的connect 函数 没有action 没有dispatch
没有reducer ~~~
复制代码
import React from 'react'
import ReactDOM from 'react-dom'
import { GlobalProvider, GlobalContext } from './store'

const App = function (){
  const [title,setTitle] = React.useState('react-redux')
  return (
    <div onClick={()=>{setTitle('react-hooks')}}>{title}</div>
  )
}

ReactDOM.render(
  <GlobalProvider>
    <App />
  </GlobalProvider>
  , document.getElementById('root'))

复制代码

实验

在src 下面新建components文件夹 新建两个文件做为验证

├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── components ├──button.js
    |              ├──show.js
    |
    ├── index.js
    ├── store.js
    

复制代码
button.js 调用store.setAppName方法
复制代码
import React from 'react'
import { GlobalContext } from '../store'

export default function ButtonComponent() {
  const store = React.useContext(GlobalContext)
  return (
    <div>
      这个是button组件,点击按钮将react-redux 变成react-hooks
      <button onClick={()=>{store.setAppName('react-hooks')}}>切换</button>
    </div>
  )
}
复制代码
show.js 用来显示appName
复制代码
import React from 'react'
import { GlobalContext } from '../store'

export default function ShowComponent() {
  const store = React.useContext(GlobalContext)
  return (
    <div>
      <h1>{store.appName}</h1>
    </div>
  )
}
复制代码
再将这两个组件整合到index.js中去
复制代码
import React from 'react'
import ReactDOM from 'react-dom'
import { GlobalProvider, GlobalContext } from './store'


import ButtonComponent from './components/button'
import ShowComponent from './components/show'

const App = function (){
  const [title,setTitle] = React.useState('react-redux')
  return (
    <div onClick={()=>{setTitle('react-hooks')}}>
      <ButtonComponent />
      <ShowComponent />
    </div>
  )
}

ReactDOM.render(
  <GlobalProvider>
    <App />
  </GlobalProvider>
  , document.getElementById('root'))


复制代码
npm start 看到效果
至此 构建工做结束
复制代码
感言: hooks 处理数据较redux 更清晰,不须要绕来绕去
若是更偏心redux的处理方式 react 也提供了reducer 

该项目地址 https://github.com/Tangpriest/hooks_demo
复制代码
相关文章
相关标签/搜索