欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

程序员文章站 2022-08-17 17:50:04
一、ES6的Set、Map数据结构 Map、Set都是ES6新的数据结构,都是新的内置构造函数,也就是说typeof的结果,多了两个: Set 是不能重复的数组 Map 是可以任何东西当做键的对象 ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 let s ......

一、es6setmap数据结构

mapset都是es6新的数据结构,都是新的内置构造函数,也就是说typeof的结果,多了两个:

set 是不能重复的数组

map 是可以任何东西当做键的对象

 

es6 提供了新的数据结构 set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

let s = new set();
s.add(1);
s.add(2);
s.add(3);
s.add(3);
s.add(3);
s.add(4);
s.add(5);
console.log(s)

 

 

 

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

集合中添加数据用add()方法,会自动过滤已经有的元素。

 

最快的数组去重方法:

let s = new set([1,2,3,3,3,4,5]);
console.log([...s])

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

let s = new set([1,2,3,4,5]);
console.log(s.size)
console.log(s.has(5))
console.log(s.delete(5))
console.log(s)

 

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

集合的关注点是在元素里面,而不关注顺序,所以不提供s[0]来枚举某项api,但是可以转为数组[...s]

 

javascript 的对象(object),本质上是键值对的集合(hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。

为了解决这个问题,es6 提供了 map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,object 结构提供了“字符串—值”的对应,map 结构提供了“值—值”的对应,是一种更完善的 hash 结构实现。如果你需要“键值对”的数据结构,map object 更合适。

let m = new map();
const o = {a:1,b:2};
m.set("haha", 123);
m.set(o, 456)
m.set(888,789)
console.log(m)
console.log(m.get(o))

 

 

 

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

使用get()来得到元素的值,key是区分类型的。


二、函数式编程库

所谓的“函数式编程”指的是程序中的函数的是“纯函数”,就表示一个函数不改变传入的参数。

我们之前大量使用...filtermap等等操作,略微麻烦,就有3个特别好用的函数式编程库应运而生。

2.1 immutable.js

2.1.1概述

来自facebook,是官方推荐的库,immutable表示不可变。immutable总是返回新的对象,不会修改原对象。

 

immutable不是深拷贝对象,创造性的使用diff算法,有一个结构共享机制,它所做的是智能分析改变,让改变后的元素可以共享改变之前的一些结构。

immutable 使用了 structural sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

{
    a:{"x":1 , "y":2},
    b:{
        c:{"x":3, "y":4},
        d:{"x":5},
    }
}
{
    a:{"x":1 , "y":2},
    b:{
        c:{"x":8, "y":4},
        d:{"x":5},
    }
}

上面代码中,颜色相同部分,还是内存中同一个对象。


2.1.2基本讲解

官方:

安装依赖:

npm install immutable --save

immutable提供了两个数据类型:

listmapimmutable自己封装的一个类,list是不可变的数组,map是不可变的对象。

 前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

fromjs() 将一个原生js数据类型转换为immutable类型的数据

tojs()   将一个immutable类型的数据转换为js类型的数据。

list()map() 用来创建新的listmap对象(将原生js对象和数组转换到不可变的maplist

 

immutable思维:

先用fromjs()list()map()将原生js的数组、对象、变为listmap对象

然后再操作,比如对数组的push操作

最后.tojs()immutable对象变为原生js的数组、对象

 

nodejs环境中引包:

var immutable = require("immutable");
var list = immutable.list

const list1 = list(["白板","幺鸡","三条","三万"])
const list2 = list1.push("四条")
console.log(list1.tojs())
console.log(list2.tojs())

会发现push之后,原数组没有改变,只返回了新数组。

上面案例是用list(原数组)将数组变为list对象,也可以用fromjs

 

var immutable = require("immutable");
var fromjs = immutable.fromjs

const list1 = fromjs(["白板","幺鸡","三条","三万"])
const list2 = list1.push("四条")
console.log(list1.tojs())
console.log(list2.tojs())

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

数组的头尾操作,也不会改变原数组,都是返回新数组:

var immutable = require("immutable");
var fromjs = immutable.fromjs

const list1 = fromjs(["白板","幺鸡","三条","三万"])
const list2 = list1.push("四条")
const list3 = list1.pop()
const list4 = list1.unshift("东风")
const list5 = list1.shift()

console.log(list1.tojs())
console.log(list2.tojs())
console.log(list3.tojs())
console.log(list4.tojs())
console.log(list5.tojs())

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

更改set

set表示更改下标为2的项为“二筒”,注意不会真的改变原数组,而是返回新数组:

const list1 = fromjs(["白板","幺鸡","三条","三万"])
const list2 = list1.set(2,"二筒");

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

对象也有set

const obj1 = fromjs({"a" : 1, "b" : 2 ,"c" : 3})
const obj2 = obj1.set("b",888)

console.log(obj1.tojs())
console.log(obj2.tojs())

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

在数组中查找某一项,使用find(),寻找某一项下标用findindex()

得到map对象的某一个键的值,要用get()方法

var immutable = require("immutable");
var fromjs = immutable.fromjs

const data = fromjs([
    {"id" : 1, "name" : "小明", "age" : 12},
    {"id" : 2, "name" : "小红", "age" : 12},
    {"id" : 3, "name" : "小强", "age" : 13},
])

const item = data.find(item=>item.get("id") == 2);
console.log(item.tojs())

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

删除用delete,删除下标为2的项

const list1 = fromjs([111,222,333,888,999]);
const list2 = list1.delete(2);
console.log(list1.tojs());
console.log(list2.tojs());

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

is()函数验证是否相等

var {is , map} = require("immutable");
let o1 = map({a : 1, b : 2, c : 3});
let o2 = map({a : 1, b : 2, c : 3});

console.log(o1 == o2);  //在内存中不相等
console.log(is(o1,o2)); //在immutable世界中是相等

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk


2.1.3真实项目场景

真实项目场景 - 增加todo,用set设置,用get获取

var immutable = require("immutable");
var fromjs = immutable.fromjs

const data = fromjs({
    "todos" : [
        {"id" : 1,"title" : "吃饭", "done" : false },
        {"id" : 2,"title" : "睡觉", "done" : false },
        {"id" : 3,"title" : "打豆豆", "done" : false },
    ],
    "show" : "all"
})

const newdata = data.set(
    "todos",
    data.get("todos").push({"id" : 4,"title" : "打架", "done" : false})
)
console.log(newdata.tojs())

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

真实项目场景 - 删除id2todo,使用delete(2)

//删除id为2的项
const newdata = data.set(
"todos", 
data.get("todos").delete(data.get("todos").findindex(item=>item.get("id")== 2)
));

console.log(newdata.tojs());

 

方法2

const newdata = data.set(
    "todos",
    data.get("todos").filter(item=>item.get("id") != 2)
)

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

真实项目场景 - 改变id2的项title为“吃鸡”

方法1

var index = data.get("todos").findindex(item=>item.get("id") == 2);
var item = data.get("todos").get(index)
const newdata = data.set("todos",data.get("todos").set(index, item.set("title","吃鸡")));

console.log(newdata.tojs())

 

方法2

const newdata = data.set("todos",data.get("todos").map(item=>{
    return item.get("id") == 2 ? item.set("title" , "吃鸡") : item;
}))

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk


2.1.4redux结合

改造todolist项目:

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

只改变reducers中的文件夹的写法,其它地方一律不改。

state的数据依然是原生js的数组和对象,只不过在reducer函数运行中,瞬间变成为immutablelistmap了,但是出去的时候就tojs了,里外里,state还是原生数组、对象。

import {fromjs , tojs} from "immutable";
const initobj = {
    "todos" : [
        {"id" : 1 , "title" : "吃饭" , "done" : false},
        {"id" : 2 , "title" : "睡觉" , "done" : true},
        {"id" : 3 , "title" : "打豆豆" , "done" : true}
    ],
    "show" : "all"         
}

export default (state = initobj, action) => {
    //下面的语句很重要,变为immutable对象
    state = fromjs(state);

    if(action.type == "addtodo"){
         return state.set("todos", state.get("todos").push(
             {
                 "id" : state.get("todos").reduce((a,b)=>{
          return b.get("id") > a ? b.get("id") : a
          }, 0) + 1,
                 "title" : action.title,
                 "done" : false
             }
         )).tojs();
    }else if(action.type == "deltodo"){
        return state.set(
"todos", 
state.get("todos").filter(item=>item.get("id") != action.id)
).tojs();
    }else if(action.type == "changetodo"){
        return state.set(
"todos", 
state.get("todos").map(
item => item.get("id") == action.id ? item.set(action.k, action.v) : item
)
).tojs();
    }else if(action.type == "changeshow"){
        return state.set("show", action.show).tojs();
    }
    return state.tojs();
}

2.2 ramda.js

纯函数,也叫作“兰姆达函数”,就是ramda这个词。

2.2.1函数柯里化基础

函数柯里化(currying),是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数,而且返回结果的新函数。柯里化函数就是逐步传参,逐步缩小函数的适用范围,逐步求解的过程。

 

简单的加法函数:

function add(x,y){
    return x + y;
}
add(2,3);//5

如果用函数柯里化接受两个参数的函数变成单一参数,如下:

function add(x) {
    return function (y){
        return x + y
    }
}

console.log(add(2)(3))

 


 

2.2.2基本讲解

npm install ramda --save

数组尾插一项:

var r = require("ramda");

var arr1 = ["红中","白板","幺鸡"];
var arr2 = r.append("一筒", arr1)
var arr3 = r.append("二筒")(arr1)

console.log(arr1)
console.log(arr2)
console.log(arr3)

被操作的元素放到最后一个参数。

 前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

数组头插一项:

var r = require("ramda");

var arr1 = ["红中","白板","幺鸡"];
var arr4 = r.prepend("发财",arr1)

console.log(arr4)

 

 

 

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk


2.2.3真实项目场景

改变对象的b属性为8

这里使用了非常重要的方法r.lensprop()聚焦到某属性,功能就是让改变的值从原基础上进行修改

var r = require("ramda");

const obj1 = {"a" : 1,"b" : 2,"c" : 3}
const obj2 = r.set(r.lensprop("b") , 8, obj1)
console.log(obj2)

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

删除id2的项:

const state = {
    "todos": [
       {"id" : 1, "title" : "吃饭",  "done" : false},
       {"id" : 2, "title" : "睡觉",  "done" : false},
       {"id" : 3, "title" : "打豆豆","done" : false}
    ],
    "show":"all"
}

//删除id为2的项
const newstate = r.set(r.lensprop("todos"), r.filter(item=>item.id != 2, state.todos) , state);
console.log(newdata)

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

修改id2的项title为吃鸡

const newstate = r.set(r.lensprop("todos"),r.map(item => item.id == 2 ? 
r.set(r.lensprop("title"),"吃鸡",item) : item , state.todos), state);

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

修改showonlydone

const newstate = r.set(r.lensprop("show") , "onlydone", state);

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

基本上一条语句能够解决问题,不再写...了,并且相比如immutable,没有maplist和对象、数组的转换。


2.2.4redux结合

还是用todolist举例,在reducers/index.js中修改,下面标黄色的语句的r.__是占位符:

var r = require("ramda");

const initobj = {
    "todos" : [
        {"id" : 1 , "title" : "吃饭" , "done" : false},
        {"id" : 2 , "title" : "睡觉" , "done" : true},
        {"id" : 3 , "title" : "打豆豆", "done" : true}
    ],
    "show" : "all"         
}

export default (state = initobj, action) => {
//r.__表示占位符,下面调用settodos时,就等于传入了要更改成为的值
    const settodos = r.set(r.lensprop("todos"), r.__ , state);
    const setshow  = r.set(r.lensprop("show") , r.__ , state);

    if(action.type == "addtodo"){
        return settodos(r.append({
            "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a, 0) + 1,
            "title" : action.title,
            "done" : false
        },state.todos));
    }else if(action.type == "deltodo"){
        return settodos(state.todos.filter(item=>item.id != action.id));
    }else if(action.type == "changetodo"){
        return settodos(state.todos.map(item=>item.id == action.id ? r.set(r.lensprop(action.k), action.v, item) : item))
    }else if(action.type == "changeshow"){
        return setshow(action.show);
    }
    return state;
}

2.3 lodash.js

2.3.1基本讲解

实际上underscore.js已经在“函数库工具”输给了lodashlodash完全可以替代underscore

官网:

中文:

中文:

npm install --save lodash

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

underscore有的函数,lodash全有,比如数组去重和最大最小值:

var _ = require("lodash");

var arr1 = [3,3,3,3,4,4,4,4,5,5,5,5,3];
var arr2 = _.uniq(arr1);

console.log(arr1);
console.log(arr2);

console.log(_.max(arr1));
console.log(_.min(arr1));

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

 

lodash中有子包,叫做fpfpfunctional programing函数式编程的意思。

需要引入这个包

var fp = require("lodash/fp");

更改b属性为8

var fp = require("lodash/fp");

var obj1 = {"a" : 1 , "b" : 2 , "c" : 3};
var obj2 = fp.set("b" , 8 , obj1);

console.log(obj1);
console.log(obj2);

 

 

 

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

和ramda一样,被操作对象写最后一个参数。


2.3.2真实项目场景

删除

var fp = require("lodash/fp");

const state = {
    "todos" : [
        {"id" : 1 , "title" : "吃1饭" , "done" : false},
        {"id" : 2 , "title" : "吃2饭" , "done" : false},
        {"id" : 3 , "title" : "吃3饭" , "done" : false}
    ],
    "show" : "all"
};

//删除id为2的项
const newstate = fp.set("todos", state.todos.filter(item => item.id != 2), state);

console.log(state);
console.log(newstate);

 

增加:

const newstate = fp.set("todos", fp.concat(
    state.todos,
    {
        "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a, 0) + 1,
        "title": "吃鸡",
        "done" : false
    }
) , state);

 

修改id2的项的title为“吃鸡”

const newstate = fp.set("todos",state.todos.map(item=>item.id == 2 ? fp.set("title", "吃鸡", item) : item), state);

如果遇见比较难的场景,此时可以用克隆方法,比如在第2项之间插入一项

const _todos = fp.clone(state.todos)

//更改克隆之后的数组
_todos.splice(2,0,{"id": 4,"title":"游泳","done":false})

//更改state
const newstate = fp.set("todos", _todos, state)
console.log(state)
console.log(newstate)
const car = {
    "cars" : {
        "a" : [
            {
                "name" : "奥迪" ,
                "series" : [
                    {
                        "name" : "a6",
                        "type" : "豪华轿车"
                    },
                    {
                        "name" : "a4",
                        "type" : "豪华轿车"
                    }
                ]
            },
            {
                "name" : "奥拓",
                "series" : [{"奥拓1号" : 2}]
            }
        ],
        "b" : [
            {"奔驰" : 1}
        ]
    }
}

//改变a6的车系为普通轿车
var newstate = fp.clonedeep(car);
newstate.cars.a[0].series[0].type = '普通轿车';

console.log(json.stringify(newstate))

2.3.3 redux结合

import fp from "lodash/fp"; 

const initobj = {
    "todos" : [
        {"id" : 1 , "title" : "吃饭" , "done" : false},
        {"id" : 2 , "title" : "睡觉" , "done" : true},
        {"id" : 3 , "title" : "打豆豆" , "done" : true}
    ],
    "show" : "all"         
}

export default (state = initobj, action) => {
    if(action.type == "addtodo"){
        return fp.set("todos" , fp.concat(state.todos , {
            "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a , 0) + 1,
            "title" : action.title,
            "done" : false
        }), state);
    }else if(action.type == "deltodo"){
        return fp.set("todos" , state.todos.filter(item => item.id != action.id) , state);
    }else if(action.type == "changetodo"){
        return fp.set("todos", state.todos.map(item=>item.id == action.id ? fp.set(action.k,action.v,item) : item) , state);
    }else if(action.type == "changeshow"){
        return fp.set("show" , action.show , state);
    }
    return state;
}

三、异步

3.1搭建服务器

我们将所有前端的东西都放入www文件夹中。

 

node.jsapp.js实现数据接口:

var express = require("express");
var app = express();
app.use(express.static("www"))

app.get("/api",(req,res)=>{
    res.json({"result":8})
})
app.listen(3000);

3.2 redux-thunk解决异步

我们现在有四个文件都没有地方适合写异步:componentsactionsconstantsreducer

所以react提供了react-thunk包,thunk是中间件,所谓的中间件就是在发出actionreducer进行改变的中间,要做的事。

 

安装依赖:

npm install --save redux-thunk

main.js

import react from "react";
import reactdom from "react-dom";
import { createstore, applymiddleware} from "redux";
import { provider } from 'react-redux'
import thunk from 'redux-thunk' 
import reducers from "./reducers/index";
import logger from "redux-logger";
//引入父组件
import app from "./containers/app";

//创建redux store 仓库用来存放状态
const store = createstore(reducers, applymiddleware(logger, thunk))

reactdom.render(
    <provider store={store}>
        <app></app>
    </provider>,
    document.getelementbyid('app')
)

 

components/counter/index.js组件,按钮点击之后做addserver

<button onclick={()=>{this.props.counteractions.addserver()}}>加服务器那么多</button>

 

此时actions/counteractions.js文件中,就可以写异步函数了:

两步:第一步请求服务器数据,第二步发出action。将服务器的返回结果,当做载荷发给reducer

import {add , minus , addserver} from "../constants/counter.js";

//同步阵营,直接返回一个action
export const add = () => ({"type" : add});
export const minus = () => ({"type" : minus});

//异步有两个(),第一个()接受按钮传的参数,第二个()是系统给你的dispatch和getstate
//export const addserver = (n)=> (dispatch, getstate)=>{ 
//    alert(n) 
//    alert(dispatch)
//    alert(getstate().counter.v)
//}

export const addserver = ()=> async (dispatch , getstate) => {
    //发出ajax请求,实际上是fetch请求,fetch不是ajax
    const {result} = await fetch("/api").then(data=>data.json());
    //发action,因为唯一能改变reducer的方法就是dispath一个action
    dispatch({"type" : addserver , result})
}

 

constants/counter.js

export const addserver = "addserver_counter";

reducers/counter.js

import {add , minus , addserver} from "../constants/counter.js";
export default (state = {"v" : 0} , action) => {
    if(action.type == add){
        ...
    }else if(action.type == minus){
        ...
    }else if(action.type == addserver){
        return {
            "v" : state.v + action.result
        }
    } 
    return state;
}

 

如果使用fetch,要安装babel插件:babel-plugin-transform-runtime

babelasync await翻译成浏览器都不认识的语句了,所以要用插件解决,不让babel翻译:

const path = require('path');
module.exports = {
    entry : "./www/app/main",                             // 入口
    output: {
        path: path.resolve(__dirname, "www/dist"),         // 出口文件夹
        filename: "bundle.js"                             // 出口文件名
    },
    watch : true,                                         // 自动检测变化,进行打包
    module: {                                            // 配置一些插件
        rules: [
            {
                test: /\.js$/,                            // 所有.js结尾的文件
                loader: "babel-loader",                // 都要使用babel-loader处理
                include: [path.resolve(__dirname, "www/app")],
                exclude: [path.resolve(__dirname, "node_modules")],
                options: {
                    presets: ["env" , "react"],
                    plugins: ["transform-object-rest-spread", "transform-runtime" ]
                }
            }
        ]
    }
}

现在讲解重要知识,如何从服务器上请求默认数据,此时要通过:

 前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

结合echarts.js使用

app.js服务端出数据接口:

var a = 0;
var b = 0;
var c = 0;
app.get("/api2" , (req,res)=>{
    res.json({
        "result": [
            { value: a, name: '清晰' },
            { value: b, name: '一般' },
            { value: c, name: '懵逼' }
        ]
    });
});

//投票接口
app.get("/toupiao/:zimu" , (req,res)=>{
    var zimu = req.params.zimu;
    if(zimu == "a") a++;
    if(zimu == "b") b++;
    if(zimu == "c") c++;
    
    res.json({
        "result": [
            { value: a, name: '清晰' },
            { value: b, name: '一般' },
            { value: c, name: '懵逼' }
        ]
    });
});

app.listen(3000);

containers/app.js

import react from 'react';
import {connect} from "react-redux";
import counter from "../components/counter/index.js";
import pie from "../components/pie/index.js";
export default class app extends react.component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div>
                <counter></counter>
                <pie></pie>
            </div>
        );
    }
}

 

components/pie/index.js组件的构造函数中调用函数:

import react from 'react';
import {connect} from "react-redux";
import {bindactioncreators} from "redux";
import * as pieactions from "../../actions/pieactions.js";

class pie extends react.component {
    constructor(props) {
        super(props);
        ///组件还没上树时,发异步请求数据
        props.pieactions.loadserver();
    }
//组件已经上树,然后初始化echart结构
    componentdidmount(){
        this.pic = echarts.init(this.refs.pic);
    }
//react开发中没有回调函数的,所以数据回来了,在组件将要更新的生命周期写
    //组件将要更新,为什么会将要更新,因为reducer中的result变了!
    //为什么它变了,因为fetch回来了,从而发出dispatch,影响result了。
    componentwillupdate(nextprops){
        //这是百度的图表插件标准写法,就是一个配置,最重要的是最后一项data,来自服务器
        var option = {
            tooltip: {
                trigger: 'item',
                formatter: "{a} <br/>{b}: {c} ({d}%)"
            },
            legend: {
                orient: 'vertical',
                x: 'left',
                data: ['清晰', '一般', '懵逼']
            },
            series: [
                {
                    name: '懵逼指数',
                    type: 'pie',
                    radius: ['50%', '70%'],
                    avoidlabeloverlap: false,
                    label: {
                        normal: {
                            show: false,
                            position: 'center'
                        },
                        emphasis: {
                            show: true,
                            textstyle: {
                                fontsize: '30',
                                fontweight: 'bold'
                            }
                        }
                    },
                    labelline: {
                        normal: {
                            show: false
                        }
                    },
                    //这里呈递数据
                    data: nextprops.result
                }
            ]
        };
        //设置option,组件就能显示图表了
        this.pic.setoption(option);
    }

    render() {
        return (
              <div>
            <p>结果:{this.props.result}</p>
                <div ref="pic" style={{"width":"300px" ,"height":"300px"}}></div>
                <button onclick={()=>{this.props.pieactions.toupiao('a')}}>清晰</button>
                <button onclick={()=>{this.props.pieactions.toupiao('b')}}>一般</button>
                <button onclick={()=>{this.props.pieactions.toupiao('c')}}>懵逼</button>
              </div>
        );
    }
}

export default connect(
    ({pie})=>({
        result: pie.result
    }),
    (dipatch)=>({
        pieactions: bindactioncreators(pieactions, dipatch)
    })
)(pie);

 

actions/pieactions.js中写异步请求数据

export const loadserver = () => async (dispatch , getstate) => {
    //异步请求数据
    const {result} = await fetch("/api2").then(data=>data.json());
    //存储到reducer
    dispatch({"type" : "loadserver" , result});
}

export const toupiao = (zimu) => async (dispatch, getstate) => {
    const { result } = await fetch("/toupiao/" + zimu).then(data => data.json());
    dispatch({ "type": "loadserver", result });
}

 

reducers/pie.js要处理action的工作

export default (state = {"result" : []} , action) => {
    if(action.type == "loadserver"){
        return {"result" : action.result};
    }
    return state;
}

 

reducers/index.js

import {combinereducers} from "redux";
import counter from "./counter.js";
import pie from "./pie.js";
//暴露合并的reducer
export default combinereducers({
    counter ,
    pie
});

前端笔记之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk