2019-05-29 19:17:26 qq_33559093 阅读数 843

先初始化一个react native的项目

npm install -g yarn react-native-cli

react-native init AwesomeProject

准备安装dva 、react-navigation

1.yarn add  dva-core

2.yarn add react-redux

3.yarn add react-navigation

4.yarn add react-native-gesture-handler

5.react-native link react-native-gesture-handler

然后是集成步骤

1.集成dva,使用dva-core和react-redux,新建app文件夹

app文件夹中新建.root.js

import * as React from 'react';
import indexModel from './models/index'
import { Provider  } from 'react-redux';
import App from './routes'//    这个是react-navigation路由文件

import { create } from 'dva-core';

const models = [indexModel];

const app = create(); // 创建dva实例,可传递配置参数。https://dvajs.com/api/#app-dva-opts

models.forEach((o) => { // 装载models对象
  app.model(o);
});

app.start(); // 实例初始化

const store = app._store; // 获取redux的store对象供react-redux使用

export default class Container extends React.Component {
  render() {
    return (
      <Provider store={store}>//    注入dva
        <App/>
      </Provider>
    );
  }
}

2.编写路由,react-navigation

app文件夹下新建routes.js

import React, { PureComponent } from 'react'
import {
  TabBarBottom, addNavigationHelpers, createSwitchNavigator,
  createBottomTabNavigator, createStackNavigator, createAppContainer
} from 'react-navigation'
import AuthLoadingScreen from './components/loading/index'
import {StatusBar, View, Platform} from "react-native";

import Home from './pages/Home/Home'
import Order from './pages/Order/Order'
import Get from './pages/Get/Get'
import Register from './pages/Register/index'
import Establish from './pages/Establish/index'
import Restore from './pages/Restore/index'

const AuthStack = createStackNavigator(
  {
    Register: Register,
    Establish: Establish,
    Restore: Restore
  },
);
const HomeNavigator = createBottomTabNavigator(
  {
    Home: { screen: Home },
    Order: { screen: Order },
    Get: { screen: Get }
  }
);

const AppNavigation = createSwitchNavigator(
  {
    App: HomeNavigator,
    Auth: AuthStack,
    AuthLoading: AuthLoadingScreen
  },
  {
    initialRouteName: 'AuthLoading',
  }
);

const App = createAppContainer(AppNavigation);

export default App

3.链接项目

根目录下的index.js

import {AppRegistry} from 'react-native';
import App from './app/root';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

最后,如何在组件中使用dva,点我的另外一篇文章----->点这里

2017-11-17 09:10:38 Apache012 阅读数 492

dva 是一个基于 react 和 redux 的轻量应用框架,redux步骤繁杂,更容易出错,搭建成本更高。

这个博客地址可以算是第一个dva+react+antd程序,但是它出来没有样式

http://www.cnblogs.com/yuanyuan0809/p/7171761.html



需要在src/router.js添加

import 'antd/dist/antd.css';

2017-12-28 16:39:39 bbsyi 阅读数 2820

 

作者:zhenhua-lee
链接:https://www.zhihu.com/question/51831855/answer/225446217
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  1. 框架: dva是个框架,集成了redux、redux-saga、react-router-redux、react-router
  2. 快速初始化: 可以快速实现项目的初始化,不需要繁琐地配置
  3. 简化开发:将initState、saga、reducer集成到一个model里面统一管理,避免文件散落在各个文件里面,便于快速查找与开发
  4. 简洁的API:整个项目中只有dva、app.model、app.router、app.use、app.start几个API
  5. 无缝对接:跟react的生态没有冲突,例如可以直接使用redux devtool工具
  6. 动态机制:app.start以后,仍然可以注册model,灵活性较高

再说说个人觉得不太爽的地方吧:

  1. namespace不统一: dva中的action.type格式是namespace/XXX,且在model中不需要添加前缀namespace,但是在组件中dispatch,却需要添加prefix
  2. action问题:action会散落在两个地方,一个是saga里面,另外一个是component dispatch的时候,当然这个问题在使用redux-saga的时候就会存在,只是dva仍然没有很好地统一起来。

 

2018-08-07 11:31:34 weixin_38340467 阅读数 1685
关于在页面使用window.location.href跳转至相应的页面处理办法 

  turn=(type)=>{
    if(type=='9k9'){
      window.location.href='/#/coupon/postageNine/:type=9k9';//跳转至9块9包邮
    }
    if(type=='chanel'){
      window.location.href='/#/coupon/postageNine/:type=chanel';//跳转至品牌清仓
    }

  }

如果需要在页面获取路径传过来的参数

首先我们需要修改路由,在路径里面加上参数 且在参数使用:

<Route path="/coupon/postageNine/:type" exact component={PostageNinePage}/>

通过如上配置我们是不是就可以点击实现页面跳转了呢

经过测试我们发现,浏览器地址已改变 但是页面是一片空白,那么是什么问题导致的呢,熟悉dva的同学都知道,应该是我们model出现问题,我们每个页面会有一个对应的model.js,我们打开model.js,如代码:

  subscriptions: {
    setup({dispatch, history}) {

       return history.listen(({pathname}) => {
         if (pathname === '/coupon/postageNine') {
           dispatch({type: 'fetch'});
         }
       });
   }

我们看一下subscriptions 这个属性,我的理解是监听路径,页面初始化的时候会进入subscription中的setup方法,通过判断路径的值然后加载数据 前面我们对路由进行修改,所以我们现在需要修改pathname的值,我们将参数加在后面看是否可行;


  subscriptions: {
    setup({dispatch, history}) {

       return history.listen(({pathname}) => {
         if (pathname === '/coupon/postageNine/:type') {
           dispatch({type: 'fetch'});
         }
       });
}

经过测试发现页面还是空白的,说明这种方式应该是不行的,那么我们应该怎么修改pathname的值呢?

这里楼主想到一个办法通过正则判断路径,话不多说直接看代码:

 return history.listen(({pathname}) => {
        const match = pathToRegexp('/coupon/postageNine/:type').exec(pathname);
         if (match) {
           console.log(match);
           dispatch({type: 'fetch', payload: type});
         }
      });

我们切换到浏览器然后再次触发点击函数,我们可以看见页面已经跳转成功有数据,且有输出match值(注意:

在使用之前我们需要 npm install path-to-regexp -save 导入依赖,然后 import pathToRegexp from 'path-to-regexp';)

我们看一下打印出来的match的值:

["/coupon/postageNine/:type=9k9", ":type=9k9", index: 0, input: "/coupon/postageNine/:type=9k9"]

那么成功跳转了,我们如何对match数组取值呢 ,我们可以了解到macth是一个类似数组的东西,取值不用多说直接上代码吧

 return history.listen(({pathname}) => {
        const match = pathToRegexp('/coupon/postageNine/:type').exec(pathname);
         if (match) {
           console.log(match);
            const type = match[1].split(":type=")[1];
           dispatch({type: 'fetch', payload: type});
         }
      });

Ok取值成功!那么如何将该值放到state中呢,如上段代码我们将type放到payload对象中

使用dispatch方法加载effect 中的 fetch方法,进入fetch 方法的时候使用yeild put 方法加载reducer方法中的saveType方法存到state中

 effects: {
    /*进入页面加载*/
    *fetch({payload:type,catId}, {call, put}) {
      console.log(type)
      //四大分类
      yield put({type:'saveType',payload:{type:type}})
},
  reducers: {
    saveType(state, {payload}){
      return {
        ...state,
        type:payload.type
      }
    }
  },

 然后在对应的页面就可以使用了!第一种方式就完成了!!

另外官方好像还提供了一种方法:

1.在Route中定义好匹配的路径和参数,例如:path="/product/:goodsname"

2.在组件中调用 { this.props.match.params.goodsname} 就可以获取设定的参数了

用class定义组件的时候dva封装了一些固定参数,在没有调用其他框架插件的时候分别为:

match, location, history, staticContext, dispatch 用this.props+以上参数就能访问这些参数的属性

各位小伙伴可以自己动手试试!!

-----------------------------------------------------------------------更新--------------------------------------------------------------------------------------------

偶然间发现一种在组件中新的方式传值,当然我这里是用的this.props.dispatch,window.location.href也可以,大致步骤和上面差不多,只需要修改两个地方,第一个地方,跳转页面的方法

使用"~"这个符号代替上面的"",代码如下:

 this.props.dispatch(routerRedux.push(`/coupon/postageNine/${type}`));

多个参数:

 this.props.dispatch(routerRedux.push(`/coupon/postageNine/${type}/${type1}/${type2}`));

然后第二个需要修改的地方就是model里面:

 setup({dispatch, history}) {
      return history.listen((location) => {
        const match = pathToRegexp('/coupon/postageNine/:type').exec(location.pathname);
        if (match) {
          var type = match[1]
          dispatch({type: 'fetch', payload: type});
        }
      });
    },

取值:第一个参数直接match[1],第二个参数直接match[2],这样值就可以取出来了,是不是比第一种方式方便多了,而且这种方式浏览器中地址更美观。

--------------------------------------------------来自不正经的程序袁 For the Peace and Love-------------------------------------------------

2018-07-13 20:37:41 weixin_40782680 阅读数 1431

目录

1、PureComponent组件

2、组件生命周期

3、关于箭头函数

4、path-to-regexp Package

5、classnames Package

6、Injected Props (e.g. location)

7、基于 action 进行页面跳转


关于dva的基础知识框架,可以查看这里,毕竟国产的框架,阿里在里面详细、全面而通俗解释了dva整体的框架知识,对刚入门使用dva的同学有很大的帮助;另外一篇个人觉得写的也非常不错的文章,有兴趣也可以去拜读一下,初识dva。本文主要总结了我在使用过程中遇到的以及周围同学建议的比较好的技巧或方法。

1、PureComponent组件

PureComponent和Component都是React中的两种内置类。前者相对于后者,有一个比较突出的特点是:PureComponent只重新渲染组件props中变化的部分值所影响的元素,如果组件props没有变化,则不会触发render方法重新渲染组件。这个特点的一个好处是可以提高应用的性能,因为往往只是props中的部分成员发生变化,却要重新渲染整个组件,这是比较鸡肋的。但是坏处是,当我们想要使用有状态的组件时,setState方法是不能触发渲染的,因为组件的props没有变化,这时候就不得不舍弃PureComponent而使用Component了。反正各有利弊,不同场合下合理区别选择。

2、组件生命周期

React组件的生命周期,在官方网站上给了全面而详细的解释。

这里比较强调的是,componentWillUpdate()和componentDidUpdate()。经过踩坑发现,这里的Update是指的Update组件的props而不是render,从这两个生命周期方法的参数也可以推测出这一点,切记切记。

3、关于箭头函数

在dva的实际工程开发中,常常用到箭头函数定义各种事件的回调函数。我目前碰到的情况一般有两种:

一是回调函数没有自定义参数(事件对象除外),这种情况比较简单。直接将回调函数写到事件回调属性上去即可(最好使用箭头函数定义回调函数,这涉及到当前组件的成员方法/事件/属性的使用问题);

二是回调函数有自己的参数,这种情况往往需要通过箭头函数将回调事件转移到自定义的回调函数上去,以便在事件发生时执行我们想要的操作。比较传统的就是在组件内重新定义一个方法,就是标准的箭头函数式定义,一般不会出问题;但是这样有一个麻烦:每次有事件回调都要单独定义一个方法,很不方便;为了偷懒,我们直接在事件回调属性上定义这个简单的回调方法,一开始我是这样的

作为ECMAScript 6的菜鸟,并没有发现什么异常,但这样写的结果是【查询】按钮的点击事件是无效的,并不会乖乖去干我想让它干的事情。其实呢,从ES6 箭头函数的语法角度来看,this.onSearch("CIP")是一个方法块,有多行语句,对于有多行语句的,需要用{}括起来,因为js需要一个符号去识别这个方法体从而老老实实的去执行他们。因此,上面的写法应该改成这样

按钮点击事件无效的问题就解决了

【切记】不要直接将带参数的回调方法写在回调事件的属性上去,这会导致无限次调用该方法而使浏览器崩溃甚至是数据库服务器崩溃,这种写法是不需要事件触发的。

【补充】有一个尚未完全解决的问题:本地运行没有问题,编译后发布在本地站点下按钮依然无效,原因正在挖掘中...

4、path-to-regexp Package

如果 url 规则比较复杂,比如 /users/:userId/search,那么匹配和 userId 的获取都会比较麻烦。这是推荐用 path-to-regexp简化这部分逻辑。

import pathToRegexp from 'path-to-regexp';

// in subscription
const match = pathToRegexp('/users/:userId/search').exec(pathname);
if (match) {
  const userId = match[1];
  // dispatch action with userId
}

5、classnames Package

在一些复杂的场景中,一个元素可能对应多个 className,而每个 className 又基于一些条件来决定是否出现。这时,classnames 这个库就非常有用。

import classnames from 'classnames';
const App = (props) => {
  const cls = classnames({
    btn: true,
    btnLarge: props.type === 'submit',
    btnSmall: props.type === 'edit',
  });
  return <div className={ cls } />;
}

这样,传入不同的 type 给 App 组件,就会返回不同的 className 组合:

<App type="submit" /> // btn btnLarge
<App type="edit" />   // btn btnSmall

6、Injected Props (e.g. location)

Route Component 会有额外的 props 用以获取路由信息。

  • location
  • params
  • children

更多详见:react-router

7、基于 action 进行页面跳转

import { routerRedux } from 'dva/router';

// Inside Effects
yield put(routerRedux.push('/logout'));

// Outside Effects
dispatch(routerRedux.push('/logout'));

// With query
routerRedux.push({
  pathname: '/logout',
  query: {
    page: 2,
  },
});

除 push(location) 外还有更多方法,详见 react-router-redux

8、dva重要概念之订阅Subscription

订阅方法接收的参数对象是谁?

这个对象属性只有dispatch和history,也就是用的最多的路由监听。

9、加载中处理小技巧——dva‐loading插件

可以自动处理 loading 状态,不用一遍遍地写 showLoading 和 hideLoading

 

【待续...】

 

 

react+dva+antd

阅读数 370

react+dva

博文 来自: cater_bjut

react-dva 笔记

阅读数 20

没有更多推荐了,返回首页