提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
现在网路上找到的文章里几乎都不是taro3.0的,参照他们的写法,在taro3.0上使用@tarojs/redux是无法使用的
// 这种写法在taro3.0是错误的
import { Provider } from '@tarojs/redux';
// 还有
import { connect } from '@tarojs/redux';
提示: 正确的使用方法
import { Provider } from 'react-redux';
// 还有
import { connect } from 'react-redux';
下面介绍在taro3.0中怎么使用dva
一、安装依赖
1.安装redux、 react-redux 等依赖包
npm install --save react-redux
npm install --save redux @tarojs/redux @tarojs/redux-h5 redux-thunk redux-logger
2.安装dva
npm install --save dva-core dva-loading
dva-core:封装了 redux 和 redux-saga 的一个插件
dva-loading:管理页面的 loading 状态
二.在项目中配置dva
1.在项目src目录下创建utils文件夹,并在utils中创建dva.ts文件
dva.ts文件中的内容如下:
import { create } from "dva-core";
import { createLogger } from "redux-logger";
import createLoading from "dva-loading";
let app: any;
let store: any;
let dispatch: any;
let registered: any;
function createApp(opt) {
// redux日志
opt.onAction = []
if (opt.enableLog) {
opt.onAction.push(createLogger())
}
app = create(opt)
app.use(createLoading())
// 注入model
if (!registered) {
opt.models.forEach(model => app.model(model));
}
registered = true;
app.start()
// 设置store
store = app._store;
app.getStore = () => store;
app.use({
onError(err: any) {
console.log(err);
}
})
// 设置dispatch
dispatch = store.dispatch;
app.dispatch = dispatch;
return app;
}
export default {
createApp,
getDispatch() {
return app.dispatch
}
};
2.在src/page/index目录下创建model.ts文件(后期开发每一个页面组件都需要含有一个model.ts文件用来做当前页面的异步数据请求和数据流管理 – 原理请看dva官方文档)
文件内容如下(ts的一个简单模板):
import { AnyAction } from 'redux';
import { EffectsCommandMap } from 'dva-core';
// import * as API from './service';
import { showToast } from '@tarojs/taro';
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap,
) => void;
export interface Action<T = any> {
type: T
}
export type Reducer<S = any, A extends Action = AnyAction> = (
state: S | undefined,
action: A
) => S;
export type homeState = {
data: any;
};
export interface ModelType {
namespace: string;
state: homeState;
effects: {
effectsDomeName: Effect;
};
reducers: {
save: Reducer<homeState>;
}
}
const Model: ModelType = {
namespace: 'indexModel',
state: {
data: '测试model是否配置成功'
},
effects: {
// 此处换成自己的方法名称
* effectsDomeName({ params, callBack }, { call, put }) {
// Api是request封装的请求方法(如果有需要下一期我再下一篇axios在taro的封装
// const response = yield call(API.demo, {});
// if (Response.stattus === 200 && Response.data.status === 0) {
// callBack(response.data.result)
// }
// if (response.status === 200 && response.data.status === 1) {
// showToast({
// title: response.data.msg || '发生错误',
// icon: 'erroe'
// })
// yield put({
// type: 'save',
// payload: {
// data: response.data.result,
// }
// });
// }
},
subscriptions: {
}
},
reducers: {
save(state, { payload }) {
return { ...state, ...payload };
},
},
}
export default Model
3.在src目录下创建models文件夹,并在modes文件夹下创建index.ts(该文件的作用是用来注册当前项目中所有页面组件的model的,上一步的model.ts也可以写在models中,我习惯写在当前页面的文件夹中,类似umi的文件结构)
内容如下(就是将第2小步中src/page/index目录下创建model.ts文件引入到该文件,)
// 引入index页面下的model
import index from '../pages/index/model'
export default [index]
提示: 如果其他页面也添加了model,请继续在这个index,ts中引入model进行注册
import index from '../pages/index/model';
import mine from '../pages/mine/model';
import home from './home';
export default [index, home, mine]
4.对src/app.ts文件重命名为src/app.tsx并修改其中内容如下:
import { FC } from 'react'
import { Provider } from 'react-redux'
import dva from './utils/dva';
import models from './models';
import './app.scss';
const dvaApp = dva.createApp({
initialState: {},
models,
});
const store = dvaApp.getStore();
const App: FC = ({ children }) => {
// children 是将要会渲染的页面
return <Provider store={store} > {children} </Provider>
}
export default App;
三.在页面中使用dva
import { Component } from 'react';
import { connect } from 'react-redux'
import { showToast } from '@tarojs/taro';
import { View, Text } from '@tarojs/components'
import './index.scss'
type PropsType = {
indexModel: {
data: string
},
loading: any
}
// 将src/page/index/model.ts文件连接到src/page/index/index.tsx文件中
// 绑定indexModel
@connect((
{ loading, indexModel }: {
loading: { effects: Record<string, boolean> };
indexModel: {
data: string
}
}
) => ({
loadingStatus: loading.effects['indexModel/effectsDomeName'],
indexModel
}))
class Index extends Component {
constructor(props: PropsType) {
super(props);
this.state = {
}; //初始化state
}
componentWillMount() { }
componentDidMount() {
console.log('props :>> ', this.props);
}
componentWillUnmount() { }
componentDidShow() {
console.log('props :>> ', this.props);
showToast({
title: this.props.indexModel.data,
icon: 'success',
duration: 2000
})
}
componentDidHide() { }
render() {
return (
<View className='index'>
<Text>Hello world!</Text>
</View>
)
}
}
export default Index;
结果如下:
总结
以上是今天自己爬过的坑,希望对大家有所帮助