1. 程式人生 > >DvaJs 入門知識(詳解)總結

DvaJs 入門知識(詳解)總結

學react是會有很多疑惑,

  • 不知道需要用到ES6的哪些知識點;
  • react component 有三種寫法,都要掌握還是
  • ....

JavaScript語言

變數宣告

const 和 let
不要用var, 而是用const和let, 分別表示常量和變數。不同於var的函式作用域, const和let都是塊級作用域

const DELAY = 1000;

let  count = 0;
count = count + 1;

模板字串
模板字串提供了另一種做字串組合的方法。

const user = 'world';
console.log(`hello ${user}`);    //hello world

//多行
const content = `
    Hello ${firstName},
    Thanks for ordering ${qty} tickets to ${event}.
`;

預設引數

function  logActivity(activity = 'skiing') {
    console.log(activity);
}

logAcitity();    //skiing

箭頭函式
函式的快捷寫法,不需要通過function關鍵字建立函式,並且還可以省略return關鍵字。同時,箭頭函式還會繼承當前四昂下文的this關鍵字。
比如:

[1, 2, 3].map(x => x + 1)

等同於:

[1, 2, 3].map((function(x) {
    return x + 1;
}).bind(this));

模組的import和export


import用於引入模組,export用於匯出模組
比如:

//引入全部
import dva from 'dva';

//引入部分
import { connect } from 'dva';
import { Link, Route } from 'dva/router';

//引入全部並作為github物件
import * as github from './service/github';

//匯出預設
export default App;
//部分匯出, 需import { App } from './file'; 引入
export class App extend Component {};

ES6物件和陣列
析構賦值

析構賦值讓我們從Object或Array裡取出部分資料存為變數

//物件
const user = { name: 'guanguan', age: 2};
const { name, age } = user;
console.log(`${name} : ${age} `);        //guanguan : 2

//陣列
const arr = [1, 2];
const [foo, bar] = arr;
console.log(foo);

我們也可以析構傳入的函式引數

const add = (state, { payload } => {
    return state.concat(payload);
});

析構時還可以配alias(別名),讓程式碼更具有語義

const add = (state, { payload: todo }) => {
    return state.concat(todo);
};

物件字面量改進

這是析構的反向操作,用於重新組織一個object

const name = 'duoduo';
const age = 8;

const user = { name, age };    //{ name: 'duoduo', age: 8};

定義物件方法時,還可以省去function關鍵字

app.model({
    reducers: {
        add() {} //等同於 add: function() {}
    },
    effects: {
        *addRemote() {}    //等同於addRemote: function*() {}
    },
});    

Spread Operator

Spread Operator即3個點...,有幾種不同的使用方法
可用於組裝陣列。

const name = 'duoduo';
const age = 8;

const user = { name, age };    //{ name: 'duoduo', age: 8};

 也可使用者獲取陣列的部分項

const arr = ['a', 'b', 'c'];
const [first, ...rest] = arr;
rest;    //['b', 'c']

//with ignore
const [first, , ...rest] = arr;
rest;    //['c']

 代替apply

function foo(x, y, z){}
const args = [1, 2, 3];

//下面兩句效果相同
foo.apply(null, args);
foo(...args);

對於Object而言,用於組合成新的Object

const foo = {
    a: 1,
    b: 2,
};

const bar = {
    b: 3,
    c: 2
};

const d = 4;

const ret = {...foo, ...bar,d };    //{ a: 1, b: 3, c: 2, d: 4}

 promise

promise用於更優雅地處理非同步請求。比如發起非同步請求:

fetch('/api/todos')
    .then(res => res.json())
    .then(data => ({ data }))
    .catch(err => ({ err }));
 

定義Promise

const delay =(timeout) => {
    return new Promise(resolve => {
        setTimeout(resolve, timeout);
    });
};

delay(1000).then(_ => {
    console.log('executed');
});

Generators
dva的effects是通過generator組織的。generator返回的是迭代器,通過yield關鍵字實現暫停功能
這是一個典型的dva effect,通過yield把非同步邏輯通過同步的方式組織起來

app.model({
    namespace: 'todos',
    effects: {
        *addRemote({ payload: todo }, { put, call }) {
            yield call(addTodo, todo);
            yield put({ type: 'add', payload: todo });
        },    
    },
});

React Component

Stateless Functional Component

react Compnent 有三種定義方式,分別是React.createClass, class和Stateless Functional Component。推薦使用最後一種,保持簡潔和無狀態,這是函式,不是Object,沒有this作用域。

比入定義App Component

function App(props){
    function handleClick(){
        props.dispatch({ type: 'app/create' })
    }
    return <div onClick={handleClick}>${props.name}</div>
}

JSX

Component巢狀

類似HTML,JSX裡可以給元件新增子元件

<App>
    <Header />
    <MainContent />
    <Footer />
</App>

className

class是保留字,所以新增樣式時,需用className替代class

<h1 className = "fancy">hello dva</h1>

JavaScript表示式

javascript表示式需要用{}括起來,會執行並返回結果。

<h1>{this.props.title}</h1>

Mapping Arrays to JSX

可以把陣列對映為JSX元素列表

<ul>
    { this.props.todos.map((todo, i) => <li key={i}>{todo}</li>)}
</ul>

註釋

儘量別用“//”做單行註釋

<h1>
    {/* multiline comment */}
    {/*
        multi
        line
        comment
    */}
    {
        //single line
    }
    Hello
</h1>

Spread Atrribute

這是JSX從ECMAScript6借鑑過來的很有用的特性,用於擴充元件props

別如:

const attrs = {
    href: 'http://example.org',
    target: '_blank',    
};
<a {...attrs}>Hello</a>

等同於

const attrs = {
    href: 'http://example.org',
    target: '_blank',    
}
<a href = {attrs.href} target = {target.target}>Hello</a>

Props

資料處理在React中是非常重要的概念之一,分別可以通過props,state和context來處理資料。而在dva中你只需要關心props

proptypes

JavaScript是弱型別語言,所以請儘量宣告propTypes對props進行校驗,以減少不必要的問題

function App(props) {
    return <div>{props.name}</div>;
}
App.propTypes = {
    name: React.PropTypes.string.isRequired,
};

內建的proptype有:

  • PropTypes.array
  • PropTypes.bool
  • PropTypes.func
  • PropTypes.number
  • PropTypes.object
  • PropTypes.string

往下傳資料:

往上傳資料:

CSS Modules

理解css Modules

一張圖理解CSS Modules的工作原理

buttom class在構建之後會被重新命名為ProductList_button_1FU0u.button是本地名稱。而 produc'tList_button_1FU0Ou是global name。你可以用簡短的描述性名字,而不需要關心命名衝突問題。

然後你要做的全部事情就是在css/less檔案裡寫.button{...},並在元件裡通過style.button來引用他。

定義全域性CSS

CSS Modules預設是區域性作用域的,想要宣告一個全域性規則,可用:global語法

.title {
    color: red;
}

:global(.title) {
    color: green;
}

然後在引用的時候:

<App className={styles.title} />         //red
<App className="title" /}                //green

className Package

在一些複雜的場景中,一個元素可能對應多個classname,而每個className又基於一些條件來決定是否出現。這時,classname這個庫就非常有用。

import classnames from 'classnames';
const App = (props) => {
    const cls = classnames({
        btn: true,
        btnLarge: props.type === 'submit',
        btnSmall: props.type === 'edit',
    });
    return <div className = { cls }/>
};

這樣,傳入不同的type給App元件,就會返回不同的className組合:

<App type = "submit" />         //btn btnLarge
<App type = "edit" /}           //btn btnSmall

Reducer

reducer是一個函式,接受state和action,返回老的或新的state。即:(state, action)=> state.

增刪改

以todos為例。

app.model({
    namespace: 'todos',
    state: [],
    reducer: {
        add(state, { payload: todo}){
            return state.concat(todo);
        },
        remove(state, { payload: id }) {
            return state.filter(todo => todo.id != id)
        },
        update(state, { payload: updateTodo }) {
            return state.map(todo => {
                if(todo.id === updatedTodo.id) {
                    return {...todo, ...updatedTodo};
                } else {
                    return todo;
                }
            });
        },
    },
});

深層巢狀的例子,應儘量避免。

Effect

app.model({
    namespace: 'todos',
    effects: {
        *addRemote({ payload: todo },{ put, call }){
            yield call(addTodo, todo);
            yield put({ type: 'add', payload: todo });
        },
    },
});

effects

put

用於觸發action。

yield put({ type: 'todo/add', payload: 'Learn Dva' });

call

用於呼叫非同步邏輯,支援promise

const result = yield call(fetch, '/todos');

select

用於從state裡獲取資料

const todos = yield select(state => state.todos);

錯誤處理

全域性錯誤處理

dva裡,effects和subscriptions的拋錯全部會走onError hook,所以用在onError裡統一處理錯誤。

const app = dva({
    onError(e, dispatch) {
        console.log(e.message);
    },
});

然後effects裡的拋錯和reject的promise就都會被捕獲到了。

本地錯誤處理

如果需要對某些effects的錯誤進行特殊處理,需要在effect內部加 try , catch

app.model({
    effect: {
        *addRemote() {
            try{
                //your code here
            } catch(e) {
                console.log(e.message);
            }
        },
    },
});

非同步請求

非同步請求基於whatwg-fetch

GET和POST

import request from '../util/request';

//GET
request('/api/todos');

//POST
request('/api/todos', {
    method: 'POST',
    body: JSON.stringify({a: 1}),
});

統一錯誤處理

假如約定後臺返回一下格式時, 做統一的錯誤處理

{
    status: 'error',
    message: '',
}

編輯utils/request.js,加入以下中介軟體。

function parseErrorMessage({ data }) {
    const { status, message } = data;
    if(status === 'error' ){
        throw new Error(message);
    }
    return { data };
}

然後,這類錯誤就會走到onError hook裡。

Subscription

subscription是訂閱,用於訂閱一個數據源,然後根據需要dispatch相應的action。資料來源是可以是當前的時間/伺服器的websocket連線,keyboard輸入,geolocation變化,history路由變化等。格式為({ dispatch, history })=> unsubscribe

非同步資料初始化

比如:當用戶進入/users頁面時,觸發action user/fetch載入使用者資料。

app.model({
    subscriptions: {
        setup({ dispatch, history })=>{
            history.listen(({ pathname }) => {
                if(pathname === '/users') {
                   dispatch({
                        type: 'users/fetch',
                    });
                }
            });
        },
    },
});

path-to-regexp Package

如果url規則比較複雜,比如/users/:userId/search,那麼匹配和userId的獲取都會比較麻煩這裡推薦用path-to-regexp簡化這部分邏輯

import pathToRegexp from 'path-to-regexp';

// in subscription
const match = pathToRegexp('/users/:userId/search').exec(pathname);
if (match) {
  const userId = match[1];
  // dispatch action with userId
}

Router

config with JSX Element (router.js)

<Route path = "/" component = {App} />
    <Route path = "accounts" component = {Accounts} />
    <Route path = "statements" compnent = {Statements} />
</Route>

Router Components

Route Components 是指 ./src/routes/目錄下的檔案,他們是./src/router.js裡匹配

通過connect繫結資料

import { connect } from 'dva';
function App() {}

function mapStateToProps(state, ownProps) {
    return {
        users: state.users,
    };
}
export default connect(mapStateToProps)(App);

然後在App裡就有了dispatch和users兩個屬性

injected Props(e.g.location)

Route Compotent 會有額外的props用以獲得路由資訊

  • location
  • params

基於action進行頁面跳轉

import { routerRedux } from 'dva/router';

//Inside Effects
yield put(routerRedux.push('/logout'));

//Out Effects
dispatch(routerRedux.push('/logout'));

//with query
routerRedux.push({
    pathname: '/logout',
    query: {
        page: 2,
    },
});

除push(location) 外還有更多方法

dva配置

Redux Middleware

比如要新增redux-logger中介軟體:

import createLogger from 'redux-logger';

const app = dva({
    onAction: createLogger(),
});

注:onAction支援陣列,可同時傳入多箇中間件

history

切換history為browserHistory

import { browserHistory } from 'dva/router';
const app = dva({
    history: browserHistory,
});

去除hashHistory下的_k查詢引數

import { useRouterHistory } from 'dva/router';
import { createHashHistory } from 'history';
const app = dva({
    history: userRouterHistory(createHashHistory)({querykey: false}),
});

工具

通過dva-cli建立專案

先安裝dva-cli

$ npm install dva-cli -g

然後建立專案

$ dva new myapp

最後,進入目錄並啟動

$ cd myapp
$ npm start

相關推薦

DvaJs 入門知識()總結

學react是會有很多疑惑, 不知道需要用到ES6的哪些知識點; react component 有三種寫法,都要掌握還是 .... JavaScript語言 變數宣告 const 和 let 不要用var, 而是用const和let, 分別表示常量和變數。不同於v

SQL與NoSQL資料庫入門基礎知識

SQL與NoSQL資料庫入門基礎知識詳解 這幾年的大資料熱潮帶動了一激活了一大批hadoop學習愛好者。有自學hadoop的,有報名培訓班學習的。所有接觸過hadoop的人都知道,單獨搭建hadoop裡每個組建都需要執行環境、修改配置檔案測試等過程。對於我們這些入門級新手來說簡直每個都是坑。

Thrift入門初探(2)--thrift基礎知識

  Thrift使用一種中間語言IDL,來進行介面的定義,下面來具體講一下IDL可定義的幾種常用資料型別和關鍵字. 常用資料型別及關鍵字   基本型別     thrift不支援無符號的型別,無符號型別可以簡單理解為不能表示負數,只能表示正數的型別,像java的基本資料型別都是有符號的型別. byte:

Scrapy 爬蟲框架入門案例

tin mon setting 爬蟲框架 finished perror project 原因 create 歡迎大家關註騰訊雲技術社區-博客園官方主頁,我們將持續在博客園為大家推薦技術精品文章哦~ 作者:崔慶才 Scrapy入門 本篇會通過介紹一

跨域問題相關知識(原生js和jquery兩種方法實現jsonp跨域)

syn con 加載 developer 兩種方法 ray exe 編寫 分組 1、同源策略 同源策略(Same origin policy),它是由Netscape提出的一個著名的安全策略。同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽

XPath ,總結

ava functions scripting 進一步 uri sch ble pro new XPath是W3C的一個標準。它最主要的目的是為了在XML1.0或XML1.1文檔節點樹中定位節點所設計。目前有XPath1.0和XPath2.0兩個版本。其中Xpath1

目錄--知識

性能 函數 eight 協議 小程序 循環 連接 串行 腳本 python(1)- 初識python python(2)- python程序的編寫簡單介紹 python(3)- 循環語句:從最內層跳出多層循環 python(4)- 簡單練習:py

Python內置函數——總結

模塊 可叠代對象 4.5 sea eva 映射 ring @property post 2個多月來,將3.5版本中的68個內置函數,按順序逐個進行了自認為詳細的解析,現在是時候進行個總結了。為了方便記憶,將這些內置函數進行了如下分類: 數學運算(7個)

Hibernate基礎知識

seq 每次 事務 name rep cfg 默認 poj 產生 一、Hibernate框架 Hibernate是一個開放源代碼的對象關系映射框架,它對 JDBC進行了非常輕量級的對象封裝,它將POJO類與數據庫表建立映射關系,是一個 全自動的ORM框架

JAVA 類和對象基礎知識

默認 抽象 實現 面向對象 nbsp 分組 sed fcc closed /*文章中用到的代碼只是一部分,需要源碼的可通過郵箱聯系我 [email protected]*/ 和C++一樣,JAVA也是一門面向對象的語言,其基礎和核心是類和對象。而面向對象的思想是來源與顯示生

HTTP服務相關基礎知識

gen 註冊表 關閉 return 我們 不同ip地址 跳轉 http請求 mime類型 1 HTTP服務 1.1 IP/PV/UV UV、PV=1:5關系 UV 每天訪問人數PV page view 頁面瀏覽量 通過nginx日誌統計UV PV 或通過代碼統計 ?

動態路由協議RIP,OSPF基礎知識,以及配置實驗驗證

多個 shadow star 下一跳 tle water 外交 協議 使用 動態路由:不需要手工寫路由,將各自的直連網段宣告出去,路由器之間就可以相互學習,如果路由表有變化則及時更新宣告給相鄰的路由器靜態路由 優點:精確轉發,由管理員手動控制 缺點:靈活性差動態路由特點

RabbitMQ基礎知識

bmc vhost 完成 rdquo 限流 接收消息 服務器 廣播 lazy 什麽是MQ? MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程序對應用程序的通信方法。MQ是消費-生產者模型的一個典型的代表,一端往消息隊列中不斷寫入消息,而另

Netty 入門示例

本文導讀 在已經瞭解完《Netty 理論詳解》之後,想必已經開始躍躍欲試了,畢竟這麼好的東西呀! 本文將詳細講解 Netty 入門案例。 Netty 官網地址:http://netty.io/ GitHub 託管地址:https://github.com/netty/ne

Hibernate - 檢索策略入門

檢索資料時的 2 個問題: 不浪費記憶體:當 Hibernate 從資料庫中載入 Customer 物件時, 如果同時載入所有關聯的 Order 物件, 而程式實際上僅僅需要訪問 Customer 物件, 那麼這些關聯的 Order 物件就白白浪費了許多記憶體。 更高的

spring-boot入門程式

1.建立一個普通的maven專案,專案名為boot-learnning 2.在pom.xml新增parent依賴 <parent> <groupId>org.springframework.boot</groupId> <

java基礎原來這麼容易入門

8種基本型別 int 整形 long 長整形 short 段整形 double 雙精度 float 單精度 char 字元型別 boolean 布林型別 byte 位元組型別 2 1995年由sun公司開發的 2009年 由oracle收購 3 2種技術平臺 java SE:標準版 java

ant 入門

轉載的地址(也是轉載,未找到原文地址)】:https://www.cnblogs.com/jsfx/p/6233645.html 1,什麼是antant是構建工具2,什麼是構建概念到處可查到,形象來說,你要把程式碼從某個地方拿來,編譯,再拷貝到某個地方去等等操作,當然不僅與此,但是主要用來幹這

C++多型與繼承基本知識

一、類繼承 C++是一種面向物件的語言,最重要的一個目的就是——提供可重用的程式碼,而類繼承就是C++提供來擴充套件和修改類的方法。類繼承就是從已有的類中派生出新的類,派生類繼承了基類的特性,同時可以新增自己的特性。實際上,類與類之間的關係分為三種:代理、組合和繼承。以下是三種關係的圖解

tensorflow入門案例——MNIST神經網路識別

1. MNIST下載去官網http://yann.lecun.com/exdb/mnist/ 下載4個檔案:訓練影象集/訓練標籤集/測試影象集/測試標籤集在tensorflow example mnist的目錄下面新建MNIST_data資料夾,然後把下載的4個MNIST資料集複製進去。例如我電