react dva 碎片01

来源:互联网 发布:软件项目管理总结报告 编辑:程序博客网 时间:2024/06/05 02:37

yield

function *gen(){
yield { type: 'todos/add', payload: 'Learn Dva1' };
yield { type: 'todos/add', payload: 'Learn Dva2' };
yield { type: 'todos/add', payload: 'Learn Dva3' };

}

// gen 是一个生成器,当执行的时候,并不执行 generator 函数体,而是返回一个迭代器。迭代器具有方法,每次调用 next() 方法,函数就执行到
语句的地方。next() 方返回一个对象,其中value属性表示 yield 关键词后面表达式的值,done 属性表示是否遍历结束。generator 生成器通过的配合实现流程控制,
上面的代码执行了三次 next() ,generator 函数体才执行完毕。

var g=gen();
g.next();

执行结果:

{value:{ type: 'todos/add', payload: 'Learn Dva3' },done:true}

Reducer

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


Effects

put

用于触发 action 。

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

call

用于调用异步逻辑,支持 promise 。

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

select

用于从 state 里获取数据。

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

其实 call 是可以不用的,下面这两种等价:

yield call(usersService.fetch, { page });yield usersService.fetch({ page });

例如:

  effects: {    *fetch({ payload: { page = 1 } }, { call, put }) {      const { data, headers } = yield call(usersService.fetch, { page });      // 异步更新数据后,data 和header会自动更新,即 迭代器是 从上往下执行的,      yield put({        type: 'save',        payload: {          data,          total: parseInt(headers['x-total-count'], 10),          page: parseInt(page, 10),        },      });    },



Reduce 与Action区别

dispatching function 是一个用于触发 action 的函数,action 是改变 State 的唯一途径,但是它只描述了一个行为,而 dipatch 可以看作是触发这个行为的方式,而 Reducer 则是描述如何改变数据的。


 reducerseffects 和 subscriptions 组织 model


(1) : component 调用dispatch   触发 action ( type = namespace + method) 调用 model .

(2):model 调用service ,通过(import service 方法)

(3):service 调用后台接口


State值更新

 原先 state对象 

{ data: list, total, page }
修改如下:
{ ...state, list: listT, total: totalT }

实例

  reducers: {    save(state, { payload: { data: list, total, page } }) {      return { ...state, list, total, page };    },    remove(state, { payload: id }) {      const listT = state.list.filter(item => item.id !== id);      const totalT = state.total - 1;      return { ...state, list: listT, total: totalT };    },  },

filter()

遍历数组,在每一项元素后面触发一个回调函数,通过判断,保留或移除当前项,最后返回一个新数组。

顾名思义就是过滤。

reducers/todos.js 24行

return state.filter(todo =>        todo.id !== action.id      )

state是个任务数组,filter()里面只有一个参数,就是个箭头函数,该函数只有一个参数是todo,也就是数组的每一项元素,箭头后面那个判断语句,如果返回true则保留当前项,反之移除当前项。

有的同学会问,todo.id !== action.id前为什么没有return,这是箭头函数的语法,箭头两端就是输入输出,不用写return。如果用es5的写法就是:

return state.filter(function(todo) {
  return todo.id !== action.id
  }
)

该代码段的作用是,过滤掉任务数组中,id与指定id相同的任务。返回一个新的任务数组


map()

遍历数组,在每一项元素后面触发一个回调函数,通过计算,返回一个新的当前项,最后返回一个新数组。

reducers/todos.js 29行

return state.map(todo =>        todo.id === action.id ?          Object.assign({}, todo, { text: action.text }) :          todo      )

箭头后面的值是个三元运算符,也就是return的新元素。如果id匹配,则通过Object.assign()合并一个新的属性,也就是给todo添加或者重写一个text属性,属性值为action.text。

Object.assign()第一个参数是target,就是目标,第二个第三个以及后面的参数都是source,也就是拷贝的源,是不是很像jquery插件中的extend?

这个代码的作用是给数组中指定的任务更新text属性。


some()、every()

遍历数组,在每一项元素后面触发一个回调函数,通过判断,返回一个布尔值。some()是只要有一个满足判断,就返回true,every()是只要有一项不满足判断,就返回false。

components/MainSection.js  19 行

 const atLeastOneCompleted = this.props.todos.some(todo => todo.completed)

遍历任务数组,有一个任务的属性completed为true,就返回true。

reducers/todos.js 43行

const areAllMarked = state.every(todo => todo.completed)

遍历任务数组,每一项任务的completed属性均为true时候,返回true

reduce()

遍历数组,在每一项元素后面触发一个回调函数,经过计算返回一个累加的值。

components/MainSection.js 62行

const completedCount = todos.reduce((count, todo) =>      todo.completed ? count + 1 : count,      0    )

 

...展开属性

reducers/todos.js 20行

复制代码
return [        {          id: state.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1,          completed: false,          text: action.text        },         ...state      ]
复制代码