# dva-umi

# 前言

# 生成器

Generator 函数是 ES6 提供的⼀种异步编程解决⽅案

例子

function* fn() {
  yield 1;
  console.log(1);
  yield 2;
  console.log(2);
  yield 3;
  console.log(3);
  yield 4;
  console.log(4);
}

const f = fn();

console.log(f); //返回个迭代器

f.next(); //1  {value:1,done:false}
f.next(); //2
f.next(); //3
f.next(); //4
f.next(); //null {value:undefind,done:true}

yield 表达式后⾯的表达式,只有当调⽤ next ⽅法、内部指针指向该语句时才会执⾏

# redux-saga

redux-saga 是一个用于管理应用程序 Side Effect(副作用,例如异步获取数据,访问浏览器缓存等)的 library,它的目标是让副作用管理更容易,执行更高效,测试更简单,在处理故障时更容易

# 区别

  • think {} --> dispatch --> reducer fun --> 执行函数 --> dispatch --> reducer

  • redux-sage

监听器 --> 请求(是否异步)

# 创建

安装

npm install --save redux-saga

使用

import { createStore, applyMiddleware, combineReducers } from "redux";
import createSagaMiddleware from "redux-sage";
import logo from "./logo";
// 创建 saga
const SagaMiddleware = createSagaMiddleware();
// 注册saga 中间件
const store = createStore(
  combineReducers({ logo }),
  applyMiddleware(SagaMiddleware)
);

// 监听
SagaMiddleware.run(logo);

# 多个 sage

使用 rootSaga

import { all } from "redux-saga/effects";
import logo from "./logo";

export default function* rootSaga() {
  yield all([logo]);
}

组件中使用时 加上 命名空间

dispatch({
  type: "nameSpace/nextPage",
});

# 工作 saga - Worker saga

function* getTopics(action) {
  yield put({
    type: "loading",
  });
  const res = yield call(
    fetch,
    "https://cnodejs.org/api/v1/topics?limit=10&page=" + action.page
  );
  const data = yield res.json();
  console.log(data);
  yield put({
    type: "update",
    data: data.data,
  });
}

# 监听 saga - Watcher saga

function* watchTopics() {
  yield takeEvery("getTopics", getTopics);
}

# dva

基于 React 和 redux 的轻量级 elm 风格框架

官网地址:https://dvajs.com/ (opens new window)

# umi

插件化的企业级前端应用框架

官网地址:https://umijs.org/zh-CN (opens new window)

# 脚手架

npm install create-umi -g

# 项目安装

create-umi appName

# 目录结构

https://umijs.org/zh-CN/docs/directory-structure (opens new window)

# 要注意问题

  1. .umirc

    .umirc 最终会编译成临时文件 .umi,要注意路径问题

  1. .eslintrc
{
  "extends": "eslint-config-umi",
  "rules":{
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "off"
  }
}
  1. 鉴权处理
{
  path: '/setting',
  Routes: ["/src/components/auth"], // 路由守卫组件
  component: '../pages/setting'
}

anth

注意 在调用 dispatch 时 type 要添加 命名空间名

import React from "react";
import useUser from "../hooks/useUser";
import { useDispatch, useLocation } from "dva"
import { useEffect } from "react";
import { Redirect } from "react-router-dom"
export default function (props) {
    const user = useUser();
    const dispatch = useDispatch();
    const { pathname } = useLocation();
    useEffect(() => {
        if (!user) {
            dispatch({
                type: "user/setPrevPath",
                prevPath: pathname
            })
        }
    }, [])
    if (user) {
        return <>{props.children}</>
    }
    return <Redirect to="/login" />
}
  1. 状态管理

modules 的 effects 调用 put 时不需要 写命名空间

import api from "../assets/js/api";
export default {
    namespace: "articles",
    state:{
        articles: [],
        count: 0,
        limit: 0,
        page: 0,
        pages: 0,
    },
    reducers: {
       upload(state,payload){
            return payload.data;
       }
    },
    effects: {
        *getData({categoryId,page},{call,put}){
            let data;
            const res = yield call(api.getArticles,{categoryId,page});
            data = res.data.results;
            yield put({
                type: "upload",
                data
            })
        }
    }
}

# 注意

  1. console 两次

umi 环境 遵循严格模式 所以会进行 代码检查 所以 console 会打印两次

  1. 样式

样式 遵循 style-module

Last Updated: 7/5/2021, 10:14:13 PM