Redux和react-redux用法
看到很多小伙伴一见到redux就头疼,笔者今天就来说说这个redux吧。
redux及其中间件介绍,参考:https://blog.csdn.net/lilygg/article/details/118256153
一、redux是什么?
redux是一个专门做状态管理的js库(不是react插件库),它可以用在react,angular、vue等项目中,但基本与react配合使用。
所以说react不是一个完整的框架。而我们所熟知的vuex就很不一样,它只能用在vue里,是vue自己的状态管理工具库,所以vue是一个完整的框架。
作用:集中式管理react应用中多个组件共享状态
二、什么情况下使用redux
某个组件的状态,需要让其他组件可以随时拿到(共享)
一个组件需要改变另一个组件的状态(通信)
总体原则:能不用就不用,如果不用比较吃力才考虑使用
Redux三大原则(action,reducer,store):单一数据源、State是只读的、使用纯函数来执行修改。
Redux用法真没啥复杂的,简单的说吧,
Redux是一个js库,通过里边的createStore(reducer)可以生成一个store,把它导出来就可以在组件里边使用。组件需要更改数据,只需要store.dispatch({action:xx,payload:nnn})派发这样一个动作即可。
这个动作一旦被派发,就会触发reducer函数。reducer是个无副作用的纯函数。它接收两个参数:数据初始值(旧的state)和action对象,返回新的state。
在reducer纯函数里会根据action.type去做不同的数据更改操作,最终返回一个最新的状态,而不是直接更改原始数据。、
以上就是redux的基本工作流程。
在组件更改了数据之后,想要做到实时同步(实时更新数据),需要开发者手动调用store.subscribe(()=>{ //在需要拿redux数据的地方进行数据拿取操作}),实时监听store仓库中数据的变化。
想要拿到redux里的xxx数据,可以通过store.getState().xxx拿到数据xxx。
好了,光说不练假把式,大家也是看得云里雾里,废话不多说,talk is cheap,show me your code.
示例代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 页面演示 --> <button id="increment">+</button> <span id="count">0</span> <button id="decrement">-</button> <!-- 直接把redux包拔下来引入 --> <script src="./redux.min.js"></script> <script> var initialState = { count:1 } function reducer(state=initialState,action){//action是构建redux时定义好的操作 switch (action.type) { case 'incrementAction': return {...state,count:state.count+1} case 'decrementAction': return {...state,count:state.count-1} default: return state; } return state; } //创建状态 var store = Redux.createStore(reducer); //获取redux状态中的值 console.log(store.getState());//{count:1} //添加点击事件 document.getElementById('increment').addEventListener('click',(res) => { store.dispatch({type:'incrementAction'}) }); document.getElementById('decrement').addEventListener('click',(res) => { store.dispatch({type:'decrementAction'}) }); //监听redux状态值的变化 store.subscribe(() => { //把状态中的值注入到dom中 document.getElementById('count').innerText=store.getState().count; }) </script> </body> </html>
上面的是简单版redux用法。
createStore(reducer)是基础用法,createStore函数其实可以有俩参数,下面我们看一下通常在项目中的写法:
import {legacy_createStore as createStore,combineReducers,compose, applyMiddleware} from "redux"; import thunk from "redux-thunk"; const initState = { a:1 }; function reducer(state = initState,action){ const {type,payload} = action; switch(type){ case "INIT_DATA": return state+payload; default: return state; } } const devtool = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(); const store = createStore( combineReducers({reducer}), compose(applyMiddleware(thunk),devtool)
);
export default store;
注意:在最新版的redux里,createStore函数已经被legacy_createStore替代。
react-redux是react提供的一个redux辅助js库,能让我们更简单地使用redux。
- redux是redux本包!
- react-redux是负责链接React和Redux的调料包!
前面我们说过,要想达到数据实时变化,需要开发者手动调用suscribe(()=>{})。react-redux则是在此基础上简化了redux用法,不再需要用户手动suscribe(()=>{})监听数据以达到实时变化。
react-redux提供了主要提供了Provider组件传值和connect高阶函数串联我们的组件。connect函数创建的是容器组件,UI组件不直接操作state。
需要传值的组件外部可以直接套个Provider,把store传递过去。就像下面这样:
// src/index.js
// 使用Provider组件注入store
import { Provider } from 'react-redux'
import store from './store'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
)
导出的组件如果想要包装一下啊,你就调用connect函数。
// HelloWorld.js import React from 'react' // 引入connect函数创建容器组件,ui组件不直接操作state import { connect } from 'react-redux' const HelloWorld = props => { return ( <div> <div>HelloWorld,{props.value}</div> <button onClick={() => props.add(1)}>按钮</button> </div> ) } // 设置给UI组件展示的参数 const mapDispatchToProps = store => { return { value: store, } } // 设置给UI组件调用的方法 const MapDispatchToPropsNonObject = { add: payload => ({ type: 'add', payload }), } export default connect( mapDispatchToProps, MapDispatchToPropsNonObject )(HelloWorld)
以上就是redux和react-redux的基本用法。
好了,代码在于运动,生命在于呼吸。编程使我快乐,欢迎留言和互相交流,欢迎互粉!
本文参考:https://www.jianshu.com/p/cbe5347a61bc
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析