少年驰骋,仗剑天涯
愿你眼眸有星辰,心中有大海
从此,以梦为马,不负韶华
redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理。
React-redux是为方便react使用,在redux上封装的库。在实际的项目中我们可以使用redux也可以直接使用react-redux。
1.redux
1.redux的概念
redux和react之间是没有关系的,Redux支持React、angular、jQuery甚至Javascript
redux 是一个应用数据流框架,主要是解决了组件间状态共享的问题,原理是集中式管理,主要有三个核心方法,action,store,reducer
(1)单一数据源
(2)state是只读的
唯一改变state的方法就是触发action,action是一个用于描述已经发生事件的普通对象
store.dispatch({type:'COMPLETE_TODO',index:1})
(3)使用纯函数来执行修改
为了描述action如何修改state tree,你需要去编写reducers
Reducers只是一些纯函数,它接收先前的state和action,并且返回新的state.可以复用、可以控制顺序、传入附加参数
2.redux的组成
state:就是我们传递的数据,可以分为三类:DomainData、UI State、App State
(1)Action:将我们的数据从应用传递到store的载体,它是store数据的唯一来源。我们可通过store.dispatch()将action传递给store
{
type:'USE_LIST',//必须字段
list:{...}
}
// action只是描述有事件发生,并不更新state
//action的创建函数
function addAction(params){
return{
type:'add',
...params
}
}
(2)Reducer:本质是一个函数,用来响应发送过来的actions,经处理将state发生给store
接收两个参数:一是初始化state,二是action
const initState = {...}
rootReducer = (state = initState,action)=>{...return{...}}
(3)Store作为action和reducer的桥梁
import {createStore} from 'redux'
const store = createStore(传递reducer)
拥有以下属性和方法:
State | 应用的数据状态 |
---|---|
getState | 获取数据状态 |
Dispatch | 发送action |
Subscribe | 注册监听,Subscribe的返回值注销监听 |
redux的使用例子:
1.创建store/index.js
store就是保存数据的地方,可以看作是一个容器。
import { createStore } from "redux";
//导入已经创建的reducer
import {reducer} from '../reducer'
export default createStore(reducer)
2.创建action/index.js
Action 就是 View 发出的通知,表示 State 应该要发生变化了。
Action 是一个对象。其中的type
属性是必须的,表示 Action 的名称。其他属性可以自由设置.
const sendAction = ()=>{
return {
type:'send_action',
value:'发送了某个数据——--'
}
}
module.exports = {
sendAction
}
3.创建reducer/index.js
store 收到 action 以后,会给一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
//第一个参数为state,我们可以定义默认值,然后进行赋值
//在函数中判断第二个参数action的type值是否是我们发送的,是则通过return返回新的state,
//将reducer导出
/**
* 专门处理发送过来的action
*/
const reducer = (state={value:'默认值'},action)=>{
console.log('reducer',state,action)
switch (action.type) {
case 'send_action':
return Object.assign({},state,action)
default:
return state;
}
}
module.exports = {
reducer
}
4.在组件中的使用
import { Button } from "antd";
import React, {Component} from "react";
import store from "../../store";
import {sendAction} from "../../action"
class UrlList extends Component{
constructor(props){
super(props)
//也可以使用箭头函数哈
this.handleClick = this.handleClick.bind(this)
}
handleClick(){
const action = sendAction()
store.dispatch(action)
}
//当组件加载完毕来监听
componentDidMount () {
console.log(this.context.router)
store.subscribe(()=>{
//通过store.getState().value来获取state中的值
console.log('subscribe',store.getState().value)
this.setState({})
})
}
render(){
return (
<>
<Button onClick={this.handleClick}>按钮发送</Button>
<h1>{store.getState().value}</h1>
</>
)
}
}
export default Com
2.react-redux
React-redux中的两个核心成员:Provider、Connect
Provider:这个组件使得整个app都能获取到store中的数据
Connect:使得组件能够跟store关联
2-1.provider
- Provider包装在根组件的最外层,使得所有组件都可以拿到state
- Provider接收state作为props,通过context往下传递,这样react中任何组件都可以通过context获取store
2-2.connect
- Provider 内部组件如果想要使用到state中的数据,就必须要connect进行层包裹封装,换-句话来说就是必须要被connect进行加强
- connect 就是方便我们组件能够获取到store中的state
(1)react-redux的安装:
yarn add redux
yarn add react-redux
(2)构建store和reducer
1.创建reducer/index.js文件,构建reducer来响应actions
//render/index.js
//一、state 二、action
let initState={
count:0
}
exports.reducer = (state = initState, action) => {
switch (action.type) {
case 'send_action':
return {
count:state.count+1
}
default:
return state;
}
}
2.创建store/index.js文件,通过createStore方法,把我们的reducer传入进来
import { createStore } from "redux";
//导入已经创建的reducer
import {reducer} from '../reducer'
export default createStore(reducer)
(3)Provider的实现
1.导入Provider组件,在react-redux中进行导入
2.需要利用Provider组件,对我们整个结构进行包裹
3.给我们Provider组件设置store的属性,而这个属性值是通过createStore构建出的store实例对象
import './App.css';
import ComA from './pages/ComA'
import ComB from './pages/ComB'
import store from "./store";
import { Provider } from 'react-redux';
function App() {
return (
<Provider store={store}>
<ComA/>
<ComB/>
</Provider>
);
}
export default App;
(4)connect
对connect简单分析一下
mapStateToProps方法:connect
的第一个参数传入的,而且会在每次store
中的state改变时调用。用户获取state 中的数据,必须有返回值(普通对象)。
参数 | 备注 |
---|---|
state | 必传 |
ownProps | 非必传,自己的props |
mapDispatchToProps:connect
的第二个参数传入的,用于将操作分配给store.
dispatch
是 Redux store 的一个函数。你调用 store.dispatch 来调度一个动作。这是触发状态更改的唯一方法。
第三个是要加强的组件
Connect(mapStateToProps,mapDispatchToProps)(要加强的组件)
2.3 小案例来看一下:
我们实现从在ComB中点击按钮+1,在ComA中获取+1后的值。
所以说ComB是发送方,ComA是接收方。
实现步骤:
1.导入connect
2.利用connect对组件进行加强
import React, {Component} from "react";
import {connect} from 'react-redux'
class ComB extends Component{
handleClick=()=>{
console.log('ComB',this.props)
this.props.sendAction()
}
render(){
return (
<>
<button onClick={this.handleClick}>按钮+1</button>
</>
)
}
}
const mapDispatchToProps = (dispatch)=>{
return {
//将sendAction注册到ComB的props中,然后就直接在ComB中直接使用this.props.sendAction()
sendAction:()=>{
dispatch({
type:'send_action'
})
}
}
}
export default connect(null,mapDispatchToProps)(ComB)
//connect(null,mapDispatchToProps)(ComB)
第一个参数:要接收的函数
第二个参数:要发送action的函数
第三个参数:后面的括号里面是要加强的组件
3.在ComA的组件方法中可以通过this.props拿到sendAction
import React, {Component} from "react";
import { connect } from "react-redux";
class ComA extends Component{
render(){
console.log('Home render',this.props)
return (
<>
<div>
{this.props.count}
</div>
</>
)
}
}
const mapstateToProps = (state)=>{
console.log('Home',state)
return state;
}
export default connect(mapstateToProps)(ComA)
//简写:
//export default connect((state)=>state)(ComA)
大概总结一下整个流程:
本篇是个人的一个笔记,随手记一下,分享给对大家有用!前端路上,与君共勉!