【React】Redux、React-Redux简介及应用

Redux

Redux简介

Reudx是一款JavaScript状态管理容器,除了和React配合使用,还可以配合JS、Vue使用。

工作流程

在这里插入图片描述
Redux采用的是一种发布-订阅的模式。有一个公共仓库store,这个仓库里面存储了整个应用的状态

  • 当React组件要改变状态的时候,首先会生成一个action,然后通过dispatch函数将aciton派发给store
  • store会将原来的状态state和action传递给Reducers
  • Reducers接收到这两个参数后,会对原来的状态进行修改,得到一个新的状态,再将新的状态回传给store
  • 此时store中的状态改变,然后React组件重新渲染内容。

注意:

  • 整个应用有且仅有一个store,其内部的state tree存储整个应用的state
  • state是只读的,想要修改state只能通过派发action到reducers。为了描述action如何改变state,需要编写reducer纯函数。

例子

首先先安装redux模块:

yarn add redux

Counter.js:

import React,{Component} from "react";
import store from "../store/store";
import {bindActionCreators} from "redux"; //绑定动作生成者
//actions
function add(){
	return {
		type:'ADD'
	}
}
function minus(){
    return {
        type:'MINUS'
    }
}
const actions={add,minus}   把两个动作放到一个对象里面去
const bindActions=bindActionCreators(actions,store.dispatch) //把动作对象一次性绑定到dispatch上

class Counter extends Component{
    constructor(props) {
        super(props);
        this.state={
            number:store.getState().count
        }
    }
    componentDidMount() {   //最后需要添加上这个函数,用于订阅store,页面上显示的内容才会改变
        this.unSubscribe=store.subscribe(()=>{
            this.setState({
                number:store.getState().count
            })
        })
    }
    componentWillUnmount() {      //组件卸载时取消订阅
        this.unSubscribe&&this.unSubscribe()   //已经订阅,并且调用了取消订阅函数。最后卸载组件就取消订阅
    }
    render(){
        return (
            <div>
                <p>{this.state.number}</p>
                {/*<button onClick={()=>store.dispatch({type:'ADD'})}>Count++</button>  /!*派发以及action都在触发事件里的写法,dispatch函数用于派发一个action动作*!/*/}
                {/*<button onClick={()=>store.dispatch({type:'MINUS'})}>Count--</button>*/}
                <button onClick={bindActions.add}>Count++</button>    //action和dispatch绑在一块的写法
                <button onClick={bindActions.minus}>Count--</button>

            </div>
        )
    }
}
export default Counter;
  • redux 提供了 bindActionCreators 功能,将派发 action 的函数与 store.dispatch 进行绑定。
  • 手动导入store文件,手动订阅store
  • store提供getState()方法获取state;dispatch(action)方法更新state;subscribe(listener)注册监听器。

store.js:

import {createStore} from 'redux';    //createStore函数,用来生成Store
export const ADD='ADD';   //定义接收到的动作
export const MINUS='MINUS';
function reducer(state={count:0},action){
	switch(action.type){
		case ADD:
			return {count:state.count+1}
		case MINUS:
            return {count:state.count-1}
        default:
            return state
	}
}
//创建store
let store=createStore(reducer)
export default store;
  • Redux 提供createStore这个函数,用来生成 Store。
  • reducer 必须是个纯函数,接收 state, action 两个参数。state 是旧的状态,不可直接修改,而是需要根据 action.type 不同,来生成新的 state 并返回。

App.js:
在这里插入图片描述

可以看出,在React组件中使用store,需要手动引入store文件,手动订阅store中状态的变化,这是不合理的,接下来看看React-Redux是如何做的。

React-Redux

React-Redux简介

React-Redux是Redux的官方React绑定库。能够使React组件从Redux store中读取数据,并且向store分发actions以更新数据。

例子

React-Redux不是Redux的内置,需要单独安装,两者一般结合使用。

(1)首先安装模块:

npm install redux
npm install react-redux

(2)创建一个store.js文件

import {createStore} from "redux";
export const ADD='ADD';
export const MINUS='MINUS';
function reducer(state={count:0},action){
    console.log('Action:',action)
    switch(action.type){
        case ADD:
            return{
                count:state.count+1
            }
        case MINUS:
            return {
                count:state.count-1
            }
        default:
            return state;
    }
}
let store=createStore(reducer);
export default store;

(3)index.js文件进行配置

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {Provider} from "react-redux";
import store from "./react_redux/store/store";

ReactDOM.render(
    <Provider store={ store }>
        <App />
    </Provider>,
    document.getElementById('root')
);
  • Provider是react-redux提供的一个React组件,用于把state传给它的所有子组件。这里Provider的子组件是App,而App的子组件包含Counter组件,所以就可以从这里将store里面的state传递给Counter组件。

App.js:

import Counter from "./react_redux/components/1counter";
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <Counter/>
      </header>
    </div>
  );
}
export default App;

Counter组件:

import React,{Component} from "react";
import {connect} from "react-redux";
import action from "../action/action";
class Counter extends Component{
    render(){
        return (
            <div>
                <p>{this.props.count}</p>
                <button onClick={this.props.add}>Count++</button>
                &nbsp;&nbsp;&nbsp;
                <button onClick={this.props.minus}>Count--</button>
            </div>
        )
    }
}
const mapStateToProps=(state)=>state  //得到当前的state(state是store里面的,通过index,js中Provider分发state——>App——>Counter)
const mapDispatchToProps={...action}   //得到action

export default connect(mapStateToProps,mapDispatchToProps)(Counter)  //把state和dispatch的动作绑定到当前组件Counter,生成一个新的组件
  • connect:高阶组件,给它传入一个组件,它会返回新的组件
  • mapStateToProps:定义该参数,组件监听Redux store的变化。任何时候只要store发生变化,mapStateToProps函数就会被调用。(相当于将state放入了props中
  • mapDispatchToProps:如果传递的是一个对象,那么该对象里的每一个函数都将作为Redux action creator。(相当于把action里面的所有动作都放到props中

action.js:

function add(){
    return {
        type:'ADD'
    }
}
function minus(){
    return {
        type:'MINUS'
    }
}

const action={add,minus}      //把动作打包到常量

export default action;
  • action是store数据的唯一来源,它是一个对象,里面必须有type来指定其类型。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值