学习redux
我们大多数人的学习过程一般是——一个循序渐进、逐步迭代的过程,而redux的学习却不是这样,你不看概念,就没法理解示例demo,你不敲示例demo,你就无法完全理解redux的各种基础概念。所以最终发现,redux的最好的学习方式就是,通读一个个的概念,敲出示例demo,再根据示例demo,反过来理解概念,循环往复,总能学的懂!! const todo={ TOGGLE_TODO:'TOGGLE_TODO', GET_TODOS:'GET_TODOS', toggleTodo({ items,id }) { return { type: todo.TOGGLE_TODO, items:items, id:id } }, getTodos({items}){ return { type:todo.GET_TODOS, items:items } } }; export default todo; // ====== export default function(state = {默认值}, action) { switch(action.type){ case GET_TODOS: return {todos:[...action.items]} case TOGGLE_TODO://deleted=true return { todos:action.items.map((i)=>{ if(i.id===action.id){ return { ...i, status:i.status===0?1:0 } }else{ return { ...i } } }) } default: return state; } } const store = createStore(todo); redux-hook dva.jsnpm install dva-cli -g
入门文档
put 用于触发action put({type:types.ADD})
call 用于调用异步逻辑,支持promise
call(第一个参数是一个方法,第二个是传入这个方法的参数)
take 等待dispatch 匹配某个action
yield 方法(传入方法的参数) //跟上面等同
run() 方法是添加功能 * yield
effect 都是一个简单对象
select 用于从state里获取数据
定义路由 router/Products.js import React from 'react'; const Products = (props) => ( <h2>List of Products</h2> ); export default Products; 添加路由 router.js <Route path='/products' exact component={Products}/> 编写组件 components/编写组件.js 定义Model model/..js export default { namespace:'count', state:0, reducers:{ add(count){return count+1}, minus(count){return count-1} } } 在indexjs 载入 app.model(require('./models/products').default); function IndexPage(props) { return ( <div> <h3> {props.count}</h3> <button key={'add'} onClick={()=>{props.dispatch({type:'count/add'})}}>+</button> <button key={'munus'} onClick={()=>{props.dispatch({type:'count/minus'})}}>-</button> </div> ); } IndexPage.propTypes = {}; export default connect(({count}) => ({count}))(IndexPage);react react-redux react-saga
react-sage是更好的处理异步
dva科普
function* g1() { yield 2; yield 3; yield 4; } function* g2() { yield 1; yield* g1(); yield 5; } var iterator = g2(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: 4, done: false } console.log(iterator.next()); // { value: 5, done: false } console.log(iterator.next()); // { value: undefined, done: true } yield* 表达式用于委托给另一个generator 或可迭代对象。yarn add roadhog
UMI.js全局安装umi cnpm install -g umi
路径似路由
umi div 执行
umi g 创建一些页面
umi g page index 是根路径 创建 umi 项目 yarn create 项目名 import React from 'react' import dva from 'dva' import Counter from './Counter' //dva 是一个函数 通过执行它可以拿到一个app 对象 let app = dva(); // function delay(ms) { // return new Promise(function (resolve, reject) { // setTimeout(function () { // resolve() // }, ms) // }) // } // // function getAmount() { // return fetch('http://localhost:3000/amount').then(res => res.json()); // } //app.router app.start() app.model //一个模板就是一个状态,然后把reducer和状态写在一起 //添加一个模型 app.model({ //命名空间: 因为一个应用会有很多个模型,每一个模型有一个对象 namespace: 'counter', //此命名空间的默认状态 state: {current: 0, height: 0}, //他是用来接收action ,修改仓库状态 reducers: { //reducer接受老状态和动作,返回新状态 //state老状态(parameter) action:AnyAction add(state, action) { // let current = state.current + action.payload; // return {current, height: current > state.height ? current : state.height} return {current: state.current + 1} }, // minus(state, action) { // return {...state, current: state.current - action.payload} // } }, //它是用来执行副作用的,比如说异步操作,调用api接口 effects: { //表示这是一个generator effect=redux-saga/effects // * add(action, {call, put}) { // //表示这是一个generator // //amount 是接口中的变量 call 调用方法 // let {amount}=yield call(getAmount); // //type;'方法' // yield put({type:'add',payload:amount}) // // yield call(delay, 1000); // // yield put({type: 'minus'})//可以不加前缀,counter/minus/派发其他的可以写 // } }, }); //参数是一个函数,此应用本身就是要熏染函数的返回值 app.router(() => <Counter />); //本质是启动应用,就是通过app.router获取组件,通过ReactDOM渲染到容器上 app.start('#root'); import React from 'react'; import {connect} from 'dva'; import './Counter.css'; class Counter extends React.Component { render() { return (<div> <div className={'container'}> <p>当前记录{this.props.current}</p> <button onClick={() => this.props.dispatch({type: 'counter/add'})}>add</button> </div> </div>) } } export default connect( state => state.counter )(Counter);