背景
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
复制代码