赖同学


  • 首页

  • 标签

  • 分类

  • 归档

  • 站点地图

  • 留言

  • 搜索

Dva 学习笔记 (中)

发表于 July 9, 2018|分类于 react相关|阅读次数: –
字数统计: 1356|阅读时间: 7 min

dva 学习笔记

dva 学习笔记 代码

  1. 入门课

React 没有有解决的问题

React 本身只是一个 DOM 的抽象层,使用组件构建虚拟 DOM

开发大应用要解决的问题
通信:组件之间如何通信
数据流:数据如何和视图串联起来? 路由和数据如何绑定? 如何编写异步逻辑?

通信问题

组件会发生三种通信
想子组件发消息
向父组件发消息
向其他组件发消息

React 只提供了一种通信手段:传参

组件通信的例子

step 1

父组件拿到子组件的值

class Son extends React.Component {
  render(){
    return <input />;
  }
}
class Father extends React.Compoent {
  render() {
    return <div>
      <Son />
      <p> 这里显示 Son 组件的内容
    </div>;
  }
}
ReactDOM.render(<Father>,mountNode);

step 2

子组件通过父组件传入的函数,将自己的值再传回父组件

class Son extends React.Component {
  render() {
    return <input onChange = { this.props.onChange }>
}
class Father extends React.Component {
  constructor() {
    super();
    this.state = {
      son: ""
    }
    this.changeHandler = this.changeHandler.bind(this);
  }
  changeHandler(e){
    this.SetState({ son: e.target.value });
  }
  render() {
    return <div>
      <Son onChange = { changeHandler }>
      <p>这里展示 Son 组件的内容 { this.state.son }</p>
    </div>
  }
}

数据流问题

数据流方案
Flux ,单项数据流方案, Redux 为代表
Reactive , 响应式数据流方案 Mobx 为代表

流行的数据流方案

路由: React-Router

架构: Redux

异步操作: Readux-saga

缺点:引入多个库,项目结构复杂

dva 是什么

dva 是体验技术部开发的 React 应用框架,将上面三个 React 工具库包装在一起,简化了 API , 让开发 React 应用更加快捷和方便
`dva = React-Router + Redux + Readux -saga

dva 应用的最简结构

import dva from 'dva';
const App = () => <div> Hello dva</div>;

//创建应用
const app = dva();

//注册视图
app.router( () => <App/>)

//启动应用
app.start('#root');

数据流图

State ===(connect)== View ==(dispatch)== Action == State

State : 一个对象,保存这个应用状态
View : React 组件构成的视图层
Action : 一个对象,描述事件
connect 方法 : 一个函数,绑定 State 到 View

dispatch 方法 : 一个函数,发送 Action 到 State

State 和 view

State 是存储数据的地方,收到 Action 后,就会更新数据
View 是 React 组件构成的 UI 层,从 State 获取到数据后,就渲染成 HTML 代码。只要 State 有变化, View 就会自动更新

Action

Action 是用来描述 UI 层事件的一个对象

{ type:'click-submit-button', payload: this.form.data }

connect 方法

connect 是一个函数,绑定 State 到 View

import { connect } from 'dva'

function mapStateToProps(state) {
  return { todos: state.todos };
}
connect(mapStateToProps)(App);

connect 方法返回的也是一个 React 组件,通常称为容器组件,因为它是原始的 UI 组件的容器,即在外面包了一层 State

connect 方法传入的第一个参数是 mapStateToProps 函数, mapStateToprops 函数会返回一个对象,用于建立 State 到 Props 的映射关系

dispatch 方法

dispatch 是一个函数方法,用来将 Action 发送给 State

dispatch({ type:'click-submit', payload: this.form.data })

被 connect 的 Component 会自动在 props 中拥有 dispatch 方法

dva 应用的最简结构(带 model )

// 创建应用
const app = dva();

// 注册 Model
app.model({
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1},
  },
  effects: {
    *addAfterSecond(action, (call, put)){
      yield call(delay,1000);
      yield put({ type: 'add'});
    }
  }
});

// 注册视图
app.router( () => <ConnectedApp />);

// 启动应用
app.start('#root');

app.model

dva 提供 app.model 这个对象,所有应用逻辑都定义在它上面

const app = dva();

// 新增这一行
app.model({ /**/});

app.router( () => <App/>);
app.start('#root');

Model 对象的例子

{
  namespace: 'count',
  state: 0,
  reducers: {
    add(state) { return state + 1 },
  },
  effects: {
    *addAfter1Second(action, { call,put }) {
      yield call(delay,1000);
      yield put({ type: 'add'});
    }
  }
}

Model 对象的属性

namespace : 当前 Model 的名称,整个应用的 State ,由多个小的 Model 的 State 以 namespace 为 key 合成
state : 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出
reducers : Action 处理器,处理同步动作,用来算出最新的 state

effects : Action 处理器,处理异步动作

Reducer

Reducer 是 Action 处理器,用来处理同步操作,可以看做是 state 的计算器,它的作用是根据 Action ,从上一个 State 算出当前的 State

例子:

// count + 1
function add(state) { return state + 1; }

//往 [] 里添加一个新的 todo
function addTodo(state, action){ return [...state, action.payload]; }

//往 { todos: [], loading: true } 里添加一个新的 todo,并标记 loading 为 false
function addTodo(state, action){
  return {
    ...state,
    todos: state.todos.concat(action.payload),
    loading: false
  }
}

Effect

Action 处理器,处理异步动作,基于 Redux-sga 实现。 Effect 指的是副作用。根据函数式编程,计算以外的操作都属于 Effect ,典型的就是 I/O 操作,数据库读写

function *addAfter1Second(action. { put, all}) {
  yield(delay, 1000);
  yield put({ type: 'add'});
}

Generator 函数

Effect 是一个 Generator 函数,内部使用 yield 关键字,标识每一步的操作 (无论同步或者是异步)

call 和 put

dva 提供多个 effect 函数内部的处理函数,比较常用的是 call 和 put

总例子

app.model({
 namespace: 'count';
 state: {
 record: 0,
 current: 0,
 },
 reducers: {
  add(state) {
    const newCurrent = state.current + 1;
    return {
      ...state,
      record: newCurrent > state.record ? newCurrent: state.record,
      current: newCurrent,
    };
  },
  minus(state) {
    return { ...state, current: state.current - '1};'
  },
 },
 effects: {
  *add(action ,{ call ,put}){
    yield call( delay ,1000);
    yield put({ type: 'minus'});
  },
 },
 subscriptions: {
  keyboardWatcher({ dispatch }) {
    key( '⌘+up, ctrl+up', () => { dispatch({ type:'add'})});
  }
 }
})
dva
Dva 学习笔记 (下)
Dva 学习笔记 (上)
  • 文章目录
  • 站点概览
  1. 1.<code>dva</code> 学习笔记
    1. 1.<code>React</code> 没有有解决的问题
    2. 2.通信问题
      1. 1.组件通信的例子
    3. 3.数据流问题
      1. 1.流行的数据流方案
      2. 2.<code>dva</code> 是什么
      3. 3.<code>dva</code> 应用的最简结构
      4. 4.数据流图
      5. 5.<code>State</code> 和 <code>view</code>
    4. 4.Action
      1. 1.<code>connect</code> 方法
      2. 2.<code>dispatch</code> 方法
    5. 5.<code>dva</code> 应用的最简结构(带 <code>model</code> )
      1. 1.<code>app.model</code>
      2. 2.<code>Model</code> 对象的例子
      3. 3.<code>Model</code> 对象的属性
        1. 1.<code>Reducer</code>
        2. 2.<code>Effect</code>
      4. 4.<code>Generator</code> 函数
      5. 5.<code>call</code> 和 <code>put</code>
    6. 6.总例子
© 2018 — 2023赖彬鸿
1.6k
载入天数...载入时分秒...
0%