react中redux的介绍与使用
Posted 老张在线敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react中redux的介绍与使用相关的知识,希望对你有一定的参考价值。
1 redux是什么
1、redux是一个专门用于做状态管理的js库(不是react插件库)。
2、它可以用在react,angular,vue等项目中,但基本与react配合使用。
3、作用:集中式管理react应用中多个组件共享的状态。
4、 redux只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写
2 什么情况下需要使用redux
1、某个组件的状态,需要让其他组件可以随时拿到(共享)。
2、一个组件需要改变另一个组件的状态(通信)。
3、总体原则:能不用就不用,如果不用比较吃力才考虑使用。
3redux的方法
subscribe
:监测redux中状态的改变,如redux的状态发生了改变,就执行一次
语法:store.subscribe( ()=>{} )
dispatch
:传递action
语法:{type:'',data:''}
getState
:获取store的值
4 redux的api
createStore
:专门用于创建redux中最为核心的store对象
applyMiddleware
:中间件,用于配合redux-thunk(插件,需要引入)支持异步
combineReducers
:当有多个状态时需要使用,可以将状态合并为一个对象
4.1 react-redux的api
Provider
:无需自己给容器组件传递store,给根组件包裹一个即可
语法:<Provider store={store}>
connect
: 生成一个容器组件,并暴露(类组件使用)
语法①: connect(mapStateToProps,mapDispatchToProps)(UI组件)
直接从函数的参数中就可以获取到dispatch
mapStateToProps(state)
mapStateToProps(dispatch,ownProps)
useSelector
:相当于类组件的mapStateToProps
语法 :const state = useSelector(state=>state)
useDispatch
: 相当于类组件的mapDispatchToProps
语法:
cosnt dispatch = useDispatch()
dispatch( action动作对象 )
【注意】:useDispatch()(action对象) 直接使用会报错
5、redux&react-redux 项目结构
store
index.js 创建一个store容器
views
Lists——>这个名是看文件,语义化就好了
redux
- Actions.js 返回一个或多个动作对象,一般为`{type:'',data:''}`
- ActionsTypes.js 返回一个或多个常量,用做Actions和Reducer的type值
- Reducer.js 返回一个纯函数,用于处理动作对象
index.js 将actions和reducer函数集中导出(方便管理)
index.jsx 容器组件和UI组件的结合体
6、一个简单的todolist案列
src/store/index.js
此文件主要就是创建一个仓库
将需要用到的reducer文件引入
import { createStore, combineReducers } from 'redux';
import { reducer as lists } from '../views/todo/_index'
const reducer = combineReducers({
lists
})
// function newJson(obj) {
// var json = (new Function('return' + obj))();
// return json
// }
function newJson(obj){
return JSON.parse(obj);
}
export default createStore(reducer, newJson(localStorage.getItem(('lists'))) || {});
src/router.js
此文件主要就是做一个根组件
通过provider向下传递store
import React from 'react';
import App from './App';
import { Provider } from 'react-redux';
import Store from './store/store'
import { BrowserRouter } from "react-router-dom";
const unsubscribe = Store.subscribe(() => {
console.log(Store.getState)
localStorage.setItem('lists', JSON.stringify(Store.getState()))
})
const Router = () => {
return (
<div>
<BrowserRouter>
<Provider store={Store}>
<App />
</Provider>
</BrowserRouter>
</div>
)
}
export default Router
src/List/redux/actions.js
此文件主要是返回一个action动作对象
action动作对象必须要有一个type属性
import * as actiontypes from './actionTypes';
export const addList = (data) => ({ type: actiontypes.ADDList, data })
export const delList = (data) => ({ type: actiontypes.DELLIST, data })
src/List/redux/actionTypes.js
此文件主要是返回一个常量,目的是防止出现字母错误(默认是大写)
export const ADDList = "ADDLIST";
export const DELLIST = "DELLIST";
src/List/redux/reducer.js
此文件返回一个纯函数,用于接收dispatch传来的action,进行处理之后返回store
默认注入两个参数(preState,action)
preState需要设置初始值
reducer被第一次调用时,是store自动触发的,传递的preState是undefined
必须要有默认返回值
import * as actionTypes from './actionTypes';
const reducer = (preState = [], action) => {
const { type, data } = action;
switch (type) {
case actionTypes.ADDList:
const result = [
data,
...preState
]
console.log(result)
return result
case actionTypes.DELLIST:
preState.splice(data, 1)
return [...preState]
default:
return preState
}
}
export default reducer
src/List/_index.js
汇总action和reducer方便管理
actions文件只有一个
reducer文件或许会有多个
import * as actions from './redux/actions';
import reducer from './redux/reducer';
export { actions, reducer }
src/List/_index.js (类组件写法)
类组件中获取cannect中函数映射的值和函数都是通过props拿到的
import React,{Component} from 'react';
import { connect } from 'react-redux';
import * as actions from './redux/actions';
class View extends Component{
// 渲染函数
rLsits = () => {
let { lists } = this.props;
return lists.map((value, index) => (
<li key={index}>{value} <button onClick={()=>{this.delfn(index)}}>删除</button></li>
))
}
// 添加数据
send = () => {
let val = this.inp.value;
this.props.addLists(val)
this.inp.value=""
}
// 删除数据
delfn = (index) => {
this.props.delLists(index)
}
render() {
return (
<div>
<h2>这是一个class类组件操作数组数据的例子</h2>
<input ref={value=>this.inp=value} type="text" />
<button onClick={()=>{this.send()}}>发送</button>
{this.rLsits()}
</div>
)
}
}
// 写法一 mapDispatchToProps是一个对象
export default connect(
state => ({ lists: state.lists }),
{
addLists: actions.addList,
delLists: actions.delList
}
)(View)
// 写法二 mapDispatchToProps是一个函数
// export default connect(
// state => ({ lists: state.lists }),
// (dispatch, ownProps) => ({
// addLists: data => { dispatch(actions.addList(data)) },
// delLists: data => { dispatch(actions.delList(data)) }
// })
// )(View)
// 写法三 mapDispatchToProps为null
// 需要在UI组件内通过this.props.dispath传递action动作对象
// export default connect(
// state => ({ lists: state.lists }),
// null
// )(View)
src/List/_index.js (函数组件写法)
函数组件的值是通过useSelector拿到的
函数组件的dispatch是通过useDispatch 拿到的
import React,{useRef} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import * as actions from './redux/actions'
const View = () => {
let inp = useRef();
const state = useSelector(state=>state)
const dispath = useDispatch()
const rLsits = () => {
console.log('我执行了')
return state.lists.map((value, index) => (
<li key={index}>{value} <button onClick={()=>{delLists(index)}}>删除</button></li>
))
}
// 添加数据
const send = () => {
let val = inp.current.value;
dispath(actions.addList(val))
inp.current.value=""
}
// 删除数据
const delLists = (index) => {
dispath(actions.delList(index))
}
return (
<div>
<h2>这是一个函数组件操作数组数据的例子</h2>
<input ref={inp} type="text" />
<button onClick={send}>发送</button>
{rLsits()}
</div>
)
}
export default View;
原文链接:https://blog.csdn.net/m0_57479235/article/details/119299162
以上是关于react中redux的介绍与使用的主要内容,如果未能解决你的问题,请参考以下文章
“ES7 React/Redux/GraphQL/React-Native 片段”不适用于 javascript 文件。除了安装它,我还需要配置其他东西吗?