接触React的肯定对Redux不会陌生,但是由于新手能力欠缺,Redux使用起来会显得格外繁琐,

Dva.js是由阿里前端团队基于React,Redux,Redux-saga,Webpack开发的,简化了开发体验,

而且额外内置了React-Router 和 Fetch,所以也可以理解为一个轻量级的应用框架。

安装

npm install -g dva-cli

dva new dva-quickstart(your product name)

cd dva-quickstart

npm start

配置

1 . 新建untils文件,配置dva.js

import Taro from "@tarojs/taro";
import { create } from "dva-core";
import { createLogger } from "redux-logger";
import createLoading from "dva-loading";

let app;
let store;
let dispatch;
let registered;

function createApp(opt) {
  opt.onAction = [createLogger()]; // redux日志
  app = create(opt);
  app.use(createLoading({}));

  if (!registered) opt.models.forEach(model => app.model(model));
  registered = true;
  app.start();

  store = app._store;
  app.getStore = () => store;

  dispatch = store.dispatch;
  app.dispatch = dispatch;
  return app;
}

export default {
  createApp,
  getDispatch() {
    return app.dispatch;
  }
};

2 . app.js根目录下配置使用dva

import { Provider } from "@tarojs/redux";
import dva from "./utils/dva";
import models from "./models";
import "@tarojs/async-await";
import Index from "./pages/index";

const dvaApp = dva.createApp({
  initialState: {},
  models: models
});

dvaApp.use({
  onError(err) {
    // 这里进行错误处理和错误提示
    // console.log("err456", err.msg || err.message || err);
  }
});

const store = dvaApp.getStore();
// console.log("store", store);

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <AtMessage />
        <Index />
      </Provider>
    );
  }  
}

3 . 项目src目录项新建model文件夹,新建model.js和indexModel.js

// ==== model.js ====

import index from './indexModel';
export default [
  index
]
// ==== indexModel.js ====

export const delay = ms => {
  return new Promise(resolve => setTimeout(() => resolve("do"), ms));
  //  测试错误时使用
  // throw new Error("出错了123");
};

export default {
  namespace: "index",
  state: {
    key: "0"
  },
  // Reducer 是 Action 处理器,用来处理同步操作
  reducers: {
    add_Info(state, { key }) {
      return {
        ...state,
        key
      };
    }
  },
  // Action 处理器,处理异步动作
  effects: {
    * Eadd_Info({ payload }, { select, call, put }) {
      // console.log("==payload==", payload);
      let key= yield select(state => state.index.key);
      // yield call调用delay方法异步执行,success ? put : error
      // yield call(delay, 1000);
      yield put({
        type: "add_Info",
        key: payload ? payload + 1 : null
      });
    }
  }
};

使用

配置完毕,然后可以在页面中调用

// ==== index.js ====
import { connect } from "@tarojs/redux";

class Index extends Component {
  constructor(props) {
    super(props);
    this.R_add = this.R_add.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    // console.log(this.props, nextProps);
  }

  config = { navigationBarTitleText: "首页" };

  R_add() {
    // console.log(this.props);
    this.props.dispatch({ type: "index/E_add", payload: 1 });
  }

  handleClick(type) {
    Taro.atMessage({
      message: "消息通知",
      type: type
    });
  }

  render() {
    return (
      <View className='index'>
        <Button onClick={this.R_add}> + </Button>
      </View>
    );
  }
}
export default connect(({ index }) => ({ ...index }))(Index);