• Redux-状态管理组件


    一、简介

            react中的状态只属于某个组件。而Redux是一个全局管理js状态的架构,让组件通信更加容易。

    之前是状态在所有组件间传递,而redux通过store来实现这个功能。

    Redux特性:

    1.Single source Of truth,通过store唯一维护状态。

    2.可预测性,state + action -> new state

    3.纯函数更新store (纯函数 -> 输入决定输出)

    举个例子: 待办事项表

    1. function todos(state = [], action){
    2. switch(action.type){
    3. case 'ADD_TODO':
    4. return state.concat([{text: action.text, completed: false}]);
    5. case 'TOGGLE_TODO':
    6. return state.map(
    7. (todo, idx) => {
    8. action.index === idx ? {text: todo.text, completed: !toto.completed}
    9. : todo
    10. }
    11. )
    12. default:
    13. return state
    14. }
    15. }

    二、核心概览

    拿上图举个例子,前端ui产生了deposit和withdraw2个事件,store通过dispatcher分发对应的事件给reducer处理,reducer处理后更新state。前端ui根据state重新渲染。

    1.store

    Redux的状态机实现,store 通过state存储状态,通过dispatch传播事件,通过Reducer处理事件。

    2.action

            action表示变更事件。一般包含event type 和 context。

    3.Reducer

            reducer是状态事件处理。

    举个例子: 待办事项表

    1. function todoApp(state = initialState, action){
    2. switch (action.type){
    3. case ADD_TODO:
    4. return Object.assign({}, state, {
    5. todos:[
    6. ...state.todos,
    7. {
    8. text: action.text,
    9. completed: false
    10. }
    11. ]
    12. });
    13. default:
    14. return state;
    15. }
    16. }

    三、使用示例

    用redux实现一个简单计数器,包括增加、减少功能。

    1. import React from 'react';
    2. import {createStore} from 'redux';
    3. function run(){
    4. // store initial state
    5. const initialState = { count: 0};
    6. // reducer
    7. const counter = (state = initialState, action) => {
    8. switch (action.type){
    9. case "PLUS_ONE":
    10. return {count: state.count + 1};
    11. case "MiNUS_ONE":
    12. return {count: state.count - 1};
    13. case "CUSTOM_COUNT":
    14. return {
    15. count: state.count + action.payload.count
    16. };
    17. default:
    18. return state;
    19. }
    20. }
    21. // create store
    22. const store = createStore(counter);
    23. // Action creator
    24. function plusOne(){
    25. return {type: "PLUS_ONE"}
    26. }
    27. function minusOne(){
    28. return {type: "MINUS_ONE"};
    29. }
    30. function customCount(count){
    31. return {type: "CUSTOM_COUNT", payload:{count}};
    32. }
    33. // 订阅redux 状态变更
    34. store.subscribe(() => console.log(store.getState()));
    35. store.dispatch(plusOne());
    36. store.dispatch(minusOne());
    37. store.dispatch(customCount(5));
    38. }
    39. export default () => {
    40. <div>
    41. <button onClick={run}>Runbutton>
    42. <p>* 请打开控制台查看运行结果p>
    43. div>
    44. }

    bindActionCreators使用,工具类,可以减少显示dispatch操作

    1. import React from 'react';
    2. import {createStore, bindActionCreators} from 'redux';
    3. function run(){
    4. // store initial state
    5. const initialState = { count: 0};
    6. // reducer
    7. const counter = (state = initialState, action) => {
    8. switch (action.type){
    9. case "PLUS_ONE":
    10. return {count: state.count + 1};
    11. case "MiNUS_ONE":
    12. return {count: state.count - 1};
    13. case "CUSTOM_COUNT":
    14. return {
    15. count: state.count + action.payload.count
    16. };
    17. default:
    18. return state;
    19. }
    20. }
    21. // create store
    22. const store = createStore(counter);
    23. // Action creator
    24. function plusOne(){
    25. return {type: "PLUS_ONE"}
    26. }
    27. function minusOne(){
    28. return {type: "MINUS_ONE"};
    29. }
    30. function customCount(count){
    31. return {type: "CUSTOM_COUNT", payload:{count}};
    32. }
    33. plusOne = bindActionCreators(plusOne, store.dispatch);
    34. minusOne = bindActionCreators(minusOne, store.dispatch);
    35. customCount = bindActionCreators(customCount, store.dispatch);
    36. // 订阅redux 状态变更
    37. store.subscribe(() => console.log(store.getState()));
    38. plusOne();
    39. minusOne();
    40. customCount(5);
    41. }
    42. export default () => {
    43. <div>
    44. <button onClick={run}>Runbutton>
    45. <p>* 请打开控制台查看运行结果p>
    46. div>
    47. }

    四、结合React使用

    使用Connect功能,将redux的action和state作为props传递给组件。

    计数器组件使用样例

    1. import React from 'react';
    2. import {createStore, bindActionCreators} from 'redux';
    3. import {Provider, connect} fomr 'react-redux';
    4. // store initial state
    5. const initialState = {count: 0};
    6. // reducer
    7. const counter = (state = initialState, action) => {
    8. switch (action.type){
    9. case "PLUS_ONE":
    10. return {count: state.count + 1};
    11. case "MiNUS_ONE":
    12. return {count: state.count - 1};
    13. case "CUSTOM_COUNT":
    14. return {
    15. count: state.count + action.payload.count
    16. };
    17. default:
    18. return state;
    19. }
    20. }
    21. // create store
    22. const store = createStore(counter);
    23. // Action creator
    24. function plusOne(){
    25. return {type: "PLUS_ONE"}
    26. }
    27. function minusOne(){
    28. return {type: "MINUS_ONE"};
    29. }
    30. export class Counter extends React.Component{
    31. render(){
    32. const {count, plusOne, minusOne} = this.props;
    33. return (
    34. <div className = "counter">
    35. <button onClick = {minusOne}>-button>
    36. <span>{count}span>
    37. <button onClick = {plusOne}>+button>
    38. div>
    39. );
    40. }
    41. }
    42. // 将store的state与组件props绑定
    43. function mapStateToProps(state){
    44. return {
    45. count: state.count
    46. };
    47. }
    48. // 将store的action与组件props绑定
    49. function mapDispatchToProps(dispatch){
    50. return bindActionCreators({plusOne, minusOne}, dispatch)
    51. }
    52. // 通过connect组件将store与counter组件关联
    53. const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter) ;
    54. // 返回使用样例
    55. export default class CounterSample extends React.Component{
    56. render(){
    57. return (
    58. // prodiver 基于react context实现,可以让里面的子组件都能获取到store
    59. <Provider store = {store}>
    60. <ConnectedCounter/>
    61. Provider>
    62. );
    63. }
    64. }

  • 相关阅读:
    0047__Verilog语法入门
    后端resection部分(后方交会,PnP、P3P、EPnp、Nakano P3P)
    强化学习简介
    如何利用CSS实现三角形、扇形、聊天气泡框
    【DevPress】帮助客户在CSDN社区之上,建立完全自主可控的开发者社区
    /usr/bin/ld: cannot find -lc错误原因及解决方法
    Django(3)模型
    Docker换国内源和简单操作
    .NET周报 【5月第1期 2023-05-06】
    java项目开发经验总结
  • 原文地址:https://blog.csdn.net/qq_37011724/article/details/134489506