资讯专栏INFORMATION COLUMN

React Redux简单实现

YPHP / 2585人阅读

摘要:设计思想应用是一个状态机试图与状态是一一对应的所有的状态保存在一个对象里基本改变和就是保存数据的地方你可以把它看成一个容器整个应用只能有一个提供这个函数用来生成函数接受另一个函数作为参数返回新生成的对象对象包含所有数据如果想得到某个时点的数

设计思想

1.web应用是一个状态机,试图与状态是一一对应的.
2.所有的状态,保存在一个对象里.

基本改变和API

1.Store
Store就是保存数据的地方,你可以把它看成一个容器,整个应用只能有一个Store.
Redux提供createStore这个函数,用来生成Store.

import { createStore } from "redux";
const store = createStore(reducer);
createStore函数接受另一个reducer函数作为参数,返回新生成的Store对象.

2.State
State对象包含所有数据,如果想得到某个时点的数据,就要对Store生成快照,这种时点的数据集合,
就叫做State.当前时刻的State,可以通过store.getState()拿到.

const state = store.getState();

3.Action
state的变化,会导致view的变化,但是,用户接触不到state,只能接触到view,所以.stated的变化必须是view导致的.Action就是view发出的通知,表示state应该要发生变化了.
Action是一个对象,其中的type属性是必须的,表示Action的名称,其他属性可以自由设置.

const action = {
    type: "ADD_TODO",
    payload: "learn Redux"
};

Action的名称是ADD_TODO,它携带的信息是字符串Learn Redux.
可以这样理解,Action描述当前发生的事情,改变State的唯一方法,就是使用Action,它会运送数据到Store.

4.Action Creator
View要发送多少种信息,就会有多少种Action,可以定义一个函数生成Action,这个函数就叫ActionCreator.

const ADD_TODO = "添加 TODO";
function addToDo(text) {
    return {
        type: ADD_TODO,
        text
    }
}

5.store.dispatch()
store.dispatch()是view发出Action的唯一方法.

store.dispatch(addTODO("Learn Redux"));

6.reducer
store收到Action以后,必须给出一个新的State,这样view才会发生变化.
这种State的计算过程就叫做Reducer.
Reducer是一个函数,他接受Action和当前State作为参数,返回一个新的State.

export default (state = 0, action) => {
    switch (action.type) {
        case "INCREMENT":
            return state + 1;
        case "DECREMENT":
            return state - 1;
        case "getSource":
            return "bbbb";
        default:
            return 0;
    }
}

reducer函数收到名为ADD的action以后,就返回一个新的state,作为加法的计算结果,其他计算的逻辑,
也可以根据Action的不同来实现.
实际应用中,Reducer函数不用像上面这样手动调用,store.dispatch方法会触发Reducer的自动执行.
为此,Store需要知道Reducer函数,做法就是生成Store的时候,将Reducer传入createStore方法.

const store = createStore(reducer);

createStore接受Reducer作为参数,生成一个新的Store.以后每当store.dispatch发送过来一个新的Action,
就会自动调用Reducer,得到新的State.
7.纯函数
Reducer函数最重要的特征是,它是一个纯函数,也就是说,只要是同样的输入,必须得到同样的输出.
由于Reducer是纯函数,就可以保证同样的State,必定得到同样的view,但正因为这一点,Reducer函数里面不能改变
State,必须返回一个全新的对象.

return Object.assign({}, state, { thingToChange })
export default (state = 0, action) => {
    switch (action.type) {
        case "INCREMENT":
            return state + 1;
        case "DECREMENT":
            return state - 1;
        case "getSource":
            return "bbbb";
        case "ajax":
            return action.data;
        case "ajaxError":
            return action.data
        default:
            return 0;
    }
}

8.store.subscribe()
Store允许使用store.subscribe方法设置监听函数,一旦State发生变化,就自定执行这个函数.

store.subscribe(listener);

显然,只要把view的更新函数(render或this.setState)放入listen,就会实现view的自动渲染.
let unsubscribe= store.subscribe(() => console.log(store.getState()));
unsubscribe();

Store的实现

1.store.getState(),store.dispatch(),store.subscribe()

let { subscribe, dispatch, getState } = createStore(reducer);
Reducer的拆分

Reducer函数负责生成State,由于整个应用只有一个state对象,包含所有数据,对于大型应用来说,这个State
必然十分庞大,导致Reducer函数也十分庞大.
Redux提供了一个combineReducers方法,用于Reducer的拆分,你只要定义各个子Render函数,
然后用这个方法,将它们合成一个大的Reducer.

import { combineReducers } from "redux";

const chatReducer = combineReducers({
  chatLog,
  statusMessage,
  userName
})
工作流程

1.用户发出Action

store.dispatch(action);

2.Store自动调用Reducer,并且传入两个参数,当前State和收到的Action.Reducer会返回新的State.

let nextState = todoApp(previousState, action);

3.State一旦有变化,Store就会调用监听函数.

store.subscribe(listener);

4.listener可以通过store.getState()得到当前状态,如果使用的是React,这时可以触发重新渲染view.

function listerner() {
  let newState = store.getState();
  component.setState(newState);   
}
实例
import React, { Component } from "react";
import { render } from "react-dom";
import reducer from "../reducers/reducer.js";
import { createStore } from "redux";

const store = createStore(reducer);

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0,
            source: "aaaa",
            ajaxSource: "ajax"
        };
    }
    handleAdd = () => {
        store.dispatch({
            type: "INCREMENT"
        });
    }
    handleDel = () => {
        store.dispatch({
            type: "DECREMENT"
        });
    }
    handleGet = () => {
        store.dispatch({
            type: "getSource"
        })
    }
    handleAjax = () => {
        fetch("../api/response.json")
        .then(response => response.json())
        .then((res) => {
            store.dispatch({
                type: "ajax",
                data: res
            });
        }).catch((err) => {
            store.dispatch({
                type: "ajaxError",
                data: err
            });
        })
    }
    render() {
        let _this = this;
        store.subscribe(() => {
            let o = store.getState();
            _this.setState({
                [o.type]: store.getState()[o.type]
            })
        });
        return (
            
{ this.state.count } { this.state.source } { this.state.ajaxSource.res }
); } } render(, document.getElementById("root"));
export default (state = 0, action) => {
    switch (action.type) {
        case "INCREMENT":
            return Object.assign({}, state, {
                count: state + 1,
                type: "count"
            });
        case "DECREMENT":
            return Object.assign({}, state, {
                count: state - 1,
                type: "count"
            });
        case "getSource":
            return Object.assign({}, state, {
                source: action.dada,
                type: "source"
            });
        case "ajax":
            return Object.assign({}, state, {
                ajaxSource: action.data,
                type: "ajaxSource"
            })
        case "ajaxError":
            return Object.assign({}, state, {
                ajaxSource: action.data,
                type: "ajaxSource"
            });
        default:
            return state
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84211.html

相关文章

  • redux以及react-redux简单实现

    摘要:写在前头简介随着单页应用开发日趋复杂,需要管理比任何时候都要多的状态。如果一个的变化会引起另一个变化,那么当变化时,就可能引起对应以及另一个的变化,依次地,可能会引起另一个的变化。一些库如试图在视图层禁止异步和直接操作来解决这个问题。 写在前头 redux 简介   随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (...

    elliott_hu 评论0 收藏0
  • react-redux

    摘要:主要用于构建,被认为是中的视图。高效通过对的模拟,最大限度地减少与的交互。也就是说,用户负责视觉层,状态管理则是全部交给它。该回调函数必须返回一个纯对象,这个对象会与组件的合并。 React 定义: React 是一个用于构建用户界面的 JAVASCRIPT 库。React主要用于构建UI,React 被认为是 MVC 中的 V(视图)。 特点: 声明式设计 −React采用声明范式...

    sanyang 评论0 收藏0
  • React专题:reactredux以及react-redux常见一些面试题

    摘要:我们可以为元素添加属性然后在回调函数中接受该元素在树中的句柄,该值会作为回调函数的第一个参数返回。使用最常见的用法就是传入一个对象。单向数据流,比较有序,有便于管理,它随着视图库的开发而被概念化。 面试中问框架,经常会问到一些原理性的东西,明明一直在用,也知道怎么用, 但面试时却答不上来,也是挺尴尬的,就干脆把react相关的问题查了下资料,再按自己的理解整理了下这些答案。 reac...

    darcrand 评论0 收藏0
  • React组件设计实践总结05 - 状态管理

    摘要:要求通过要求数据变更函数使用装饰或放在函数中,目的就是让状态的变更根据可预测性单向数据流。同一份数据需要响应到多个视图,且被多个视图进行变更需要维护全局状态,并在他们变动时响应到视图数据流变得复杂,组件本身已经无法驾驭。今天是 520,这是本系列最后一篇文章,主要涵盖 React 状态管理的相关方案。 前几篇文章在掘金首发基本石沉大海, 没什么阅读量. 可能是文章篇幅太长了?掘金值太低了? ...

    ideaa 评论0 收藏0
  • React构建个人博客

    摘要:兄弟组件之间无法直接通信,它们需要利用同一层的上级作为中转站。在两个地方会用到,一是通过提交后需要拿到里面的数据,二是利用监听到发生变化后调用它来获取新的数据。 前言 在学习react的过程中,深深的被react的函数式编程的模式所吸引,一切皆组件,所有的东西都是JavaScript。React框架其实功能很单一,主要负责渲染的功能,但是社区很活跃,衍生出了很多优秀的库和工具。个人觉得...

    lyning 评论0 收藏0
  • 实例讲解react+react-router+redux

    摘要:而函数式编程就不一样了,这是模仿我们人类的思维方式发明出来的。数据流在中,数据的流动是单向的,即从父节点传递到子节点。数据流严格的单向数据流是架构的设计核心。 前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应用的过程。 代码地址:Re...

    RiverLi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<