zoukankan      html  css  js  c++  java
  • Redux的工作流程

    1.Redux 是一个专门用来管理数据业务或逻辑状态的框架,它也可以实现代码结构的规范化并提供组件之间通信的便利,而这两点,对于大型应用来说非常关键。

    2.工作流程:

    Redux 三大原则

    • 单一数据源 整个应用的 state 被存储在一个 Object tree 中,且只存在于唯一的Store中。

    • state 是只读的 唯一改变 state 的方法就是触发 action,action 是一个用于描述发生事件的普通对象,视图部分只需要表达想要修改的意图,所有修改都会被集中化处理。

    • 使用纯函数来执行修改 为了实现根据 action 修改 state值,我们就需要编写 Reducer。它是一个纯函数,接收先前的 state 和 action 返回新的 state ,随着应用的变大,你可以将它拆成多个小的 Reducer ,分别独立操作 state tree 中的不同部分。

    2.具体工作步骤

     

     

    Action

    const add =()=>{
    	return {
    		type:"add",
    		data:id,
    	}
    }

    上边函数返回的就是一个 Action,它是一个包含 type 和 data 的对象。 Action 的作用就是告诉状态管理器需要做什么样的操作,正如上边的例子,就是要添加一条信息,这样就定义了一个Action,而 data 就是你做这个操作需要的数据。

    Reducer

    reducer 是一个函数(纯函数),接受 旧 state 和 action,根据不同的 Action 做出不同的操作并返回新的 state 。即:(state, action) => state

    const reducer = (state,action)=>{
    	switch(action.type){
    		case "add":
    			state['newItemId'] = action.data;
    			return {...state};
    		case "delete":
    			delete state.newItemId;
    			return {...state};
    		default :
    			return state;
    	}
    }

    在没有任何操作的情况下,我们返回的 state 与原 state 相同。

    Store

    import { createStore } from 'redux';
    const store = createStore(reducer);

    这就是 store, 用来管理 state 的单一对象,其中有三个方法:

    • store.getState():获取state ,如上,经过 reducer 返回了一个新的 state,可以用该函数获取。

    • store.dispatch(action):发出 action,用于触发 reducer 更新 state,

    • store.subscribe(listener):监听变化,当 state 发生变化时,就可以在这个函数的回调中监听。

    React-Redux

    Redux 官方提供的 React 绑定库。

    容器组件与傻瓜组件

    在应用中,通常容器组件对于 Redux 可知,他们的子组件应该是"傻瓜的"(傻瓜组件),并且通过porps获取数据。 容器组件: 通过组件 state 属性维护自身及其子组件的数据,它可以向 Redux 发起 action ,从 Redux 获取 新state值。 傻瓜组件: 通过 props 调用回调函数,从 props 获取数据展示。

    注入 Store

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { createStore } from 'redux';
    import { Provide } from 'react-redux';
    import reducer from './reducer';
    import App from './app';
    
    const store = createStore(reducer);
    class RootComp extends React.Component{
    	render(){
    		//...
    		return (//将整个视图结构包进 Provider
    			<Provider store={store}>
    				<App/>
    			</Provider>
    		)
    	}
    }
    ReactDOM.render(<RootComp/> ,document.getElementById('root'));

    connect#

    该方法用于从 UI 组件生成容器组件,

    import React from 'react';
    import { connect } from 'react-redux';
    import Home from './home';
    
    class AppContainer extends React.Component{
    	render(
    		return (
    			<Home/>
    		);
    	)
    }
    const App = connect()(AppContainer);//这里的App就是生成的容器组件。
    export default App;

    connect( mapStateToProps , mapDispatchToProps , mergeProps , options )();

    连接 React 组件与 Redux Store

    • mapStateToProps 该参数为一个 function mapStateToProps (state,[ownProps]){...},定义该参数后组件就可以监听 Redux Store 的变化,任何时候只要store发生变化,该函数就会被调用,该函数必须返回一个纯对象,它会与组件的 props 结合,而第二个参数 ownProps 被指定时,它代表传递到该组件的props,且只要组件收到新的 props ,mapStateToProps 就被调用。

    • mapDispatchToProps 通常我们会将该参数省略,此时默认情况下,dispatch 会注入到组件的props中,在你需要出发 action 的地方(可能是某个事件函数)使用该disaptch 函数将 action 发出。

    例子:

    在上边例子中,我们只要点击下添加链接,组件就会通过点击事件触发 dispath 函数 发送 action 到 store 中的 reducer, reducer 则根据 action 的 type 来决定执行什么操作,之后在 store 中新增一条记录(newItemId)后返回一个新的 state (里边包含Store中发生改变后的所有值),由于组件使用 connect 将自己与 Store 绑定起来,Store 中的值发生变化就会执行 mapStateToProps,将新的 state 放入组件的 props,从而引发组件的渲染。

    3. 异步中间件

    也许你也已经发现了前边的介绍中有个关键的问题没解决,那就是异步操作(最典型的就是通过ajax访问后台数据)。Action 发出以后,Reducer 立即计算出 State,这叫同步Action 发出之后,过段时间再执行 Reducer,这就是异步。 如和何才能让 Reducer 在异步操作结束后自动执行呢?这就需要异步中间件来解决。

    中间件通过对 store.dispatch 进行改造,在发出 Action 和执行 Reducer 这两步之间添加其他功能。 中间件可以做很多事情,这里主要讲解异步中间件redux-promise-middleware的使用。

    //Store.js 加载中间件
    import { applyMiddleware,createStore } from 'redux';
    import createPromiseMiddleware from 'redux-promise-middleware';
    import reducer from './reducers/index';
    
    const store = createStore({//createStore 可以接受应用初始状态作为参数,这时, `applyMiddleware` 就是第三个参数。
    	reduer,
    	applyMiddleware([createPromiseMiddleware()])
    });
    export default store;

    发起异步action#

    //actions.js
    export const getTodos = () => {
      const apiUrl = `/todos`;
      return {
        type: GET_TODO,
        //属性 payload 值为 Promise 类型(中间件据此判断是否需要异步处理)
        payload: fetch(apiUrl).then(response => {
          if (!response.ok) {
            //请求返回的可能是500等错误,也会执行到这里,需将状态设置为 rejected
            return Promise.reject(response.status);
          }
          return response.json();
        })
      };
    }

    处理异步 actions#

    一般 action 的处理,发起和处理是一一对应的,而异步 action 则有三个 action 来处理,分别对应异步的三种状态

    • ${GET_TODO}_PENDING 异步请求执行后会立刻 dispatch 此 action,表示请求已发出,正在等待返回值

    • ${GET_TODO}_FULFILLED 异步请求成功后会 dispatch 此 action,注意 Response 只要回来,即使是 500,也会执行到这里

    • ${GET_TODO}_REJECTED 异步请求失败后会 dispatch 此 action

    上述三个 action 及后缀皆为中间件redux-promise-middleware的约定,不同中间件约定可能不一致。

    //reducer.js
    case `${GET_TODO}_PENDING`: {
      return {
        status: FetchStatus.LOADING,
      }
    }
    
    case `${GET_TODO}_FULFILLED`: {
      return {status: FetchStatus.SUCCESS, items: action.payload};
    }
    
    case `${GET_TODO}_REJECTED`: {
      return {status: FetchStatus.FAILURE, error: action.payload};
    }



  • 相关阅读:
    解密时遇到 填充无效 无法被移除
    固态硬盘SSD,机械硬盘HDD,4K速度对比。
    onsubmit ajax return false 无效
    chrome flash
    ubuntu base make 未找到命令
    winrar 压缩命令
    查看耗时长,CPU 100% 的SQL
    【转】SQL Server日志文件过大 大日志文件清理方法 不分离数据库
    安装老版本redis .NET 客户端
    python2.0_day22_web聊天室二
  • 原文地址:https://www.cnblogs.com/goodjobluo/p/9077010.html
Copyright © 2011-2022 走看看