React第十三章 Redux和React-Redux

213 阅读2分钟

一、redux-文档

文档必读!

二、你可能不需要redux

Redux 是负责组织 state 的⼯具,但你也要考虑它是否适合你的情况。 不要因为有⼈告诉你要用 Redux就去⽤,花点时间想使⽤了 Redux 会带来的好处或坏处。

在下⾯面的场景中,引⼊入 Redux 是比较明智的:

  • 你有着相当大量的、随时间变化的数据;
  • 你的 state 需要有⼀个单⼀可靠数据来源;
  • 你觉得把所有 state 放在最顶层组件中已无法满足需要。
  • 某个组件的状态需要共享。

三、redux

\

redux是JS应⽤的状态容器,提供可预测化的状态管理。它保证程序行为⼀致性且易于测试。

四、redux上手

⽤⼀个累加器举例

1. 需要⼀个 store 来存储数据

2. store ⾥的 reducer 初始化 state 并定义 state 修改规则

3. 通过 dispatch ⼀个 action 来提交对数据的修改

4. action 提交到 reducer 函数⾥,根据传入的 action type,返回新的state

// 创建store,src/store/ReduxStore.js
import {createStore} from 'redux'
const counterReducer = (state = 0, action) => { 
  switch (action.type) {
      case 'ADD':
        return state + 1
			case 'MINUS': 
    		return state - 1
      default:
        return state
	} 
}
const store = createStore(counterReducer)
export default store


// 创建ReduxPage
import React, { Component } from "react"; 
import store from "../store/ReduxStore";
export default class ReduxPage extends Component {
  
  componentDidMount() {
    store.subscribe(() => {
      console.log("subscribe"); 
      this.forceUpdate();
    }); 
  }
  
  add = () => store.dispatch({ type: "ADD" });
  minus = () => store.dispatch({ type: "MINUS" });
  
  render() { 
    console.log("store", store); 
    return <div>
        <p>{store.getState()}</p>
        <button onClick={this.add}>add</button>
        <button onClick={this.minus}>minus</button>
    </div>
  }
}


// 还可以在src/index.js的render⾥订阅状态变更
import store from './store/ReduxStore'
const render = ()=>{
    ReactDom.render( <App/>, document.querySelector('#root') )
} 

render()
store.subscribe(render)

如果点击按钮不能更新,因为没有订阅 (subscribe) 状态变更

五、redux检查点

1. createStore 创建 store

2. reducer 初始化、修改状态函数

3. getState 获取状态值

4. dispatch 提交更新

5. subscribe 变更订阅

六、react-redux安装

npm install react-redux --save

七、使用react-redux

react-redux提供了两个api

  • Provider: 为后代组件提供 store
  • connect: 为组件提供数据和变更⽅法
// 全局提供store,index.js
import React from 'react'
import ReactDom from 'react-dom' import App from './App'
import store from './store/'
import { Provider } from 'react-redux'
ReactDom.render( 
    <Provider store={store}>
        <App/>
    </Provider>, 
    document.querySelector('#root')
)

// 获取状态数据,ReactReduxPage.js
import React, { Component } from "react"; 
import { connect } from "react-redux";
class ReactReduxPage extends Component {
  render() {
    const { num, add, minus } = this.props; 
    return <div>
        <p>{num}</p>
        <button onClick={add}>add</button>
        <button onClick={minus}>minus</button>
    </div>
  }
};

const mapStateToProps = state => {
  return {
    num: state,
  };
};
const mapDispatchToProps = {
  add: () => {
    return { type: "add" };
  },
  minus: () => {
    return { type: "minus" };
  }
};
export default connect( 
	mapStateToProps, //状态映射 mapStateToProps
	mapDispatchToProps, //派发事件映射 
)(ReactReduxPage);

connect 中的参数:

1、state 映射

2、事件映射

八、使用修饰器函数

// 获取状态数据,ReactReduxPage.js
import React, { Component } from "react"; 
import { connect } from "react-redux";

@connect(
    state=>({num:state}),
        {
            add:()=>({type:"add"}),
            minus:()=>({type:"minus"})
        }
)
class ReactReduxPage extends Component {
  render() {
	const { num, add, minus } = this.props; 
    	return <div>
        	<p>{num}</p>
        	<button onClick={add}>add</button>
        	<button onClick={minus}>minus</button>
	</div>
  }
};
export default ReactReduxPage;