react-native,react-redux和redux配合开发

react

react-native 的数据传递是父类传递给子类,子类通过this.props.** 读取数据,这样会造成组件多重嵌套,于是用redux可以更好的解决了数据和界面View之间的关系, 当然用到的是react-redux,是对redux的一种封装。

react基础的概念包括:

1.action是纯声明式的数据结构,只提供事件的所有要素,不提供逻辑,同时尽量减少在

action 中传递的数据

2. reducer是一个匹配函数,action的发送是全局的,所有的reducer都可以捕捉到并匹配与自己相关与否,相关就拿走action中的要素进行逻辑处理,修改store中的状态,不相关就不对state做处理原样返回。reducer里就是判断语句

3.Store 就是把以上两个联系到一起的对象,Redux

应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用reducer组合 而不是创建多个

store。

4.Provider是一个普通组件,可以作为顶层app的分发点,它只需要store属性就可以了。它会将state分发给所有被connect的组件,不管它在哪里,被嵌套多少层

5.connect一个科里化函数,意思是先接受两个参数(数据绑定mapStateToProps和事件绑mapDispatchToProps)再接受一个参数(将要绑定的组件本身)。mapStateToProps:构建好Redux系统的时候,它会被自动初始化,但是你的React组件并不知道它的存在,因此你需要分拣出你需要的Redux状态,所以你需要绑定一个函数,它的参数是state,简单返回你需要的数据,组件里读取还是用this.props.*

6.container只做component容器和props绑定,

负责输入显示出来,component通过用户的要交互调用action这样就完整的流程就如此

来张图



流程如上,那么结构如下。


需要实现的效果如下, 顶部 一个轮播,下面listview,底部导航切换,数据来源豆瓣电影


程序入口

import React, { Component } from 'react';

import { AppRegistry } from 'react-native';

import App from './app/app';

export default class movies extends Component {

render() {

return(

<App/>

);

}

}

AppRegistry.registerComponent('moives', () => moives)

store 和数据初始化

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:38:09

* @modify date 2017-05-17 10:38:09

* @desc [description]

*/

import { createStore, applyMiddleware, compose } from 'redux';

import { Provider } from 'react-redux';

import thunk from 'redux-thunk'

import React, { Component } from 'react';

import Root from './containers/root';

import allReducers from './reducers/allReducers';

import { initHotshow, fetchLoading } from './actions/hotshow-action';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);

const store = createStoreWithMiddleware(allReducers);

//初始化 进入等待 首屏数据 ajax请求

store.dispatch(fetchLoading(true));

class App extends Component {

constructor(props) {

super(props);

}

render() {

return (

<Provider store={ store }>

<Root/>

</Provider>

);

}

}

module.exports = App;

action纯函数,同时把action type单独写出来。在action同目录下文件types.js

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:36:44

* @modify date 2017-05-17 10:36:44

* @desc [description]

*/

'use strict';

//首页 正在上映

export const HOTSHOW_BANNER = 'HOTSHOW_BANNER';

export const HOTSHOW_LIST = 'HOTSHOW_LIST';

export const HOTSHOW_FETCH = 'HOTSHOW_FETCH';

export const ADDMORE = 'AddMORE';

hotshow-action.js
/**

* @author ling

* @email [email protected]

* @create date 2017-05-12 04:56:43

* @modify date 2017-05-12 04:56:43

* @desc [description]

*/

import { HOTSHOW_BANNER, HOTSHOW_LIST, HOTSHOW_FETCH, ADDMORE } from './types';

import { hotshowFetch } from '../middleware/index-api';

export const addBanner = (data) => {

return {

type: HOTSHOW_BANNER,

data

}

}

//加载等待,true 显示 反之

export const fetchLoading = (bool) => {

return {

type: HOTSHOW_FETCH,

bool

}

}

export const addList = (data) => {

return {

type: HOTSHOW_LIST,

data

}

}

// 正在热映 初始请求

export const initHotshow = () => {

return hotshowFetch(addList);

}


allReducers.js 整合所有reducer

import { combineReducers } from 'redux';

import { HotShowList, Banner, fetchLoading } from './hotshow/reducers'

const allReducers = combineReducers({

hotshows: HotShowList, // 首屏数据列表 listview

banner: Banner, // 轮播

fetchload: fetchLoading, //加载中boo

});

export default allReducers;


hotshowreducer

/**

* @author ling

* @email [email protected]

* @create date 2017-05-12 04:56:34

* @modify date 2017-05-12 04:56:34

* @desc [description]

*/

import { HOTSHOW_BANNER, HOTSHOW_LIST, HOTSHOW_FETCH } from '../../actions/types';

export const HotShowList = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_LIST:

return Object.assign(

{} , state , {

data : action.data

});

default:

return state;

}

}

export const Banner = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_BANNER:

let subjects = action.data;

let data = subjects.slice(0, 5);// 前五个

return Object.assign(

{} , state , {

data : data

});

default:

return state;

}

}

export const fetchLoading = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_FETCH:

return Object.assign(

{} , state , {

data : action.bool

});

default:

return state;

}

}


api 数据请求

/**

* @author ling

* @email [email protected]

* @create date 2017-05-16 08:34:36

* @modify date 2017-05-16 08:34:36

* @desc [description]

*/

//const hotshow = 'https://api.douban.com/v2/movie/in_theaters';

// const sonshow = 'https://api.douban.com/v2/movie/coming_soon';

// const usshow = 'https://api.douban.com/v2/movie/us_box';

// const nearcinemas = 'http://m.maoyan.com/cinemas.json';

const hotshow = 'http://192.168.×.9:8080/weixin/hotshow.json';

const sonshow = 'http://192.168.×.9:8080/weixin/sonshow.json';

const usshow = 'http://192.168.×.9:8080/weixin/usshow.json';

const nearcinemas = 'http://192.168.×.9:8080/weixin/nearcinemas.json';

import { initHotshow, fetchLoading } from '../actions/hotshow-action';

export function hotshowFetch(action) {

return (dispatch) => {

fetch(hotshow).then(res => res.json())

.then(json => {

dispatch(action(json));

dispatch(fetchLoading(false));

}).catch(msg => console.log('hotshowList-err '+ msg));

}

}


containers\hotshow\index

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:44:56

* @modify date 2017-05-17 10:44:56

* @desc [description]

*/

import React, { Component } from 'react';

import { View, ScrollView } from 'react-native';

import { bindActionCreators } from 'redux';

import { connect } from 'react-redux';

import { size } from '../../util/style';

import HotShowList from './hotshow-list';

import Loading from '../../compoments/comm/loading'

import { fetchLoading, initHotshow } from '../../actions/hotshow-action';

class hotshow extends Component {

componentWillMount() {

let _that = this;

let time = setTimeout(function(){

//请求数据

_that.props.initHotshowAction();

clearTimeout(time);

}, 1500);

}

render() {

return (<View >

{this.props.fetchbool ? <Loading/> : <HotShowList/> }

</View>);

}

}

function mapStateToProps(state) {

return {

fetchbool: state.fetchload.data,

hotshows: state.hotshows.data

}

}

function macthDispatchToProps(dispatch) {

return bindActionCreators({

initHotshowAction: initHotshow,

}, dispatch);

}

export default connect(mapStateToProps, macthDispatchToProps)(hotshow);

BannerCtn 轮播用的swiper 插件, 但swiper加入 listview 有个bug就是图片不显示,结尾做答
import React, { Component } from 'react';

import { Text, StyleSheet, View, Image } from 'react-native';

import { connect } from 'react-redux';

import { bindActionCreators } from 'redux';

import Swiper from 'react-native-swiper';

import { addBanner } from '../../actions/hotshow-action';

import { size } from '../../util/style';

class BannerCtn extends Component {

render() {

let data = this.props.banner.data;

return (

<View style={{height: 200}}>

{ data !== undefined ?

<Swiper height={200} autoplay={true}>

{

data.map((item, i) => {

return ( <View key={i} style={{flex: 1, height:200}}>

<Image style={{flex: 1}} resizeMode='cover'

source={{uri: item.images.large}}/>

<Text style={style.title}> {item.title} </Text>

</View>)

})

}

</Swiper>: <Text>loading</Text>

}

</View>

);

}

}

function mapStateToProps(state) {

return {

banner: state.banner

}

}

let style = StyleSheet.create({

title: {

position: 'absolute',

width: size.width,

bottom: 0,

color: '#ffffff',

textAlign: 'right',

backgroundColor: 'rgba(230,69,51,0.25)'

}

})

export default connect(mapStateToProps)(BannerCtn);

hotshow-list

import React, { Component } from 'react';

import { Text, View, ListView, StyleSheet } from 'react-native';

import { connect } from 'react-redux';

import { bindActionCreators } from 'redux';

import { addBanner } from '../../actions/hotshow-action';

import Loading from '../../compoments/comm/loading';

import Item from '../../compoments/hotshow/item';

import Banner from './banner-ctn';

import Foot from '../../compoments/comm/foot';

class HotShowList extends Component {

constructor(props) {

super(props);

}

componentWillMount() {

//顶部轮播

let { hotshows, bannerAction } = this.props;

let subs = hotshows.data.subjects;

bannerAction(subs);

}

_renderList() {

let { hotshows } = this.props;

let ary = hotshows.data.subjects, subsAry = [], row=[];

row.push(<Banner/>);

for(let i = 0, item; item = ary[i++];) {

//一行两个

subsAry.push(

<Item key={i} rank={i} data={item}/>

);

if(subsAry.length == 2) {

row.push(subsAry);

subsAry = [];

}

}

return row;

}

_renderRow(data) {

return(

<View style={{marginTop: 1, flexWrap:'wrap', flexDirection: 'row', justifyContent: 'space-between'}}>{data}</View>

);

}

render() {

let ds = new ListView.DataSource({

rowHasChanged: (r1, r2) => r1 !== r2

});

let data = this._renderList();

this.state = {

dataSource: ds.cloneWithRows(data),

}

//removeClippedSubviews 处理 banner 图片不显示

return (

<View>

<View>

<ListView removeClippedSubviews={false} dataSource={this.state.dataSource} renderRow={this._renderRow}/>

</View>

<Foot/>

</View>

);

}

}

function mapStateToProps(state) {

return {

hotshows: state.hotshows

}

}

function macthDispatchToProps(dispatch) {

return bindActionCreators({ bannerAction: addBanner}, dispatch);

}

let style = StyleSheet.create({

listbox: {

marginBottom: 45,

}

});

export default connect(mapStateToProps, macthDispatchToProps)(HotShowList);

剩下 便是foot tab 和单个item的编写

/**

* @author ling

* @email [email protected]

* @create date 2017-05-19 08:38:19

* @modify date 2017-05-19 08:38:19

* @desc [description]

*/

import React, { Component } from 'react';

import { Text, View, Image, StyleSheet } from 'react-native';

import { size } from '../../util/style';

const width = size.width/2-0.2;

class item extends Component{

render() {

let data = this.props.data;

return(

<View style={style.box}>

<Image resizeMode='cover' style={style.avatar} source={{uri:data.images.large}}/>

<View style={style.rank}>

<Text style={style.rankTxt}>Top{this.props.rank}</Text>

</View>

<View style={style.msgbox}>

<View style={style.msgrow}>

<Text style={style.msgrowl}>{data.title}</Text>

<Text style={style.msgrowr}>评分:{data.rating.average}</Text>

</View>

<View style={style.msgrow}>

<Text style={style.msgrowl}>

{data.genres.map((item, i)=> {

if(i > 1) return;

i == 1 ? null : item += ',';

return item;

})}

</Text>

<Text style={style.msgrowr}>观影人数:{data.collect_count}</Text>

</View>

</View>

</View>

);

}

}

let style = StyleSheet.create({

box: {

width: width,

paddingBottom: 1

},

avatar: {

flex: 1,

height: 260,

},

rank: {

position: 'absolute',

top: 0,

left: 0,

backgroundColor: 'rgba(255,164,51,0.6)',

paddingVertical: 1,

paddingHorizontal: 3,

borderBottomRightRadius: 4

},

rankTxt: {

fontSize: 12,

color: '#ffffff'

},

msgbox: {

position: 'absolute',

bottom: 1,

width: width,

paddingHorizontal: 2,

backgroundColor: 'rgba(230,69,51,0.5)',

},

msgrow: {

flex: 1,

flexDirection: 'row',

justifyContent: 'space-between',

},

msgrowl: {

fontSize: 12,

color: '#ffffff'

},

msgrowr: {

fontSize: 13,

color: '#ffffff'

}

});

module.exports = item;


到此一个react-native 配合redux 编程首屏显示就大体完成了,

Swiper Image 在ListView不显示在,解决如下,测试手机微android

4.4.4,有把react-native升级为0.44.2 亲测无效

    constructor(props) {

super(props);

this.state={

visibleSwiper: false

}

}

render() {

let data = this.props.banner.data;

return (

<View style={{height: 200}}>

{ this.state.visibleSwiper ?

<Swiper/>: <Text>LOADING</Text>

}

</View>

);

}

componentDidMount() {

let time = setTimeout(() => {

this.setState({

visibleSwiper: true

});

clearTimeout(time);

}, 200);

}

关于初始ajax数据,可以在create store的时候获取数据构建初始状态,也可以在ComponentDidMount的时候去执行action发ajax,

上文写错了,github 纠正

github:

https://github.com/helloworld3q3q/react-native-redux-demo

有需要的交流的可以加个好友




react-native 的数据传递是父类传递给子类,子类通过this.props.** 读取数据,这样会造成组件多重嵌套,于是用redux可以更好的解决了数据和界面View之间的关系, 当然用到的是react-redux,是对redux的一种封装。

react基础的概念包括:

1.action是纯声明式的数据结构,只提供事件的所有要素,不提供逻辑,同时尽量减少在

action 中传递的数据

2. reducer是一个匹配函数,action的发送是全局的,所有的reducer都可以捕捉到并匹配与自己相关与否,相关就拿走action中的要素进行逻辑处理,修改store中的状态,不相关就不对state做处理原样返回。reducer里就是判断语句

3.Store 就是把以上两个联系到一起的对象,Redux

应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用reducer组合 而不是创建多个

store。

4.Provider是一个普通组件,可以作为顶层app的分发点,它只需要store属性就可以了。它会将state分发给所有被connect的组件,不管它在哪里,被嵌套多少层

5.connect一个科里化函数,意思是先接受两个参数(数据绑定mapStateToProps和事件绑mapDispatchToProps)再接受一个参数(将要绑定的组件本身)。mapStateToProps:构建好Redux系统的时候,它会被自动初始化,但是你的React组件并不知道它的存在,因此你需要分拣出你需要的Redux状态,所以你需要绑定一个函数,它的参数是state,简单返回你需要的数据,组件里读取还是用this.props.*

6.container只做component容器和props绑定,

负责输入显示出来,component通过用户的要交互调用action这样就完整的流程就如此

来张图



流程如上,那么结构如下。


需要实现的效果如下, 顶部 一个轮播,下面listview,底部导航切换,数据来源豆瓣电影


程序入口

import React, { Component } from 'react';

import { AppRegistry } from 'react-native';

import App from './app/app';

export default class movies extends Component {

render() {

return(

<App/>

);

}

}

AppRegistry.registerComponent('moives', () => moives)

store 和数据初始化

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:38:09

* @modify date 2017-05-17 10:38:09

* @desc [description]

*/

import { createStore, applyMiddleware, compose } from 'redux';

import { Provider } from 'react-redux';

import thunk from 'redux-thunk'

import React, { Component } from 'react';

import Root from './containers/root';

import allReducers from './reducers/allReducers';

import { initHotshow, fetchLoading } from './actions/hotshow-action';

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);

const store = createStoreWithMiddleware(allReducers);

//初始化 进入等待 首屏数据 ajax请求

store.dispatch(fetchLoading(true));

class App extends Component {

constructor(props) {

super(props);

}

render() {

return (

<Provider store={ store }>

<Root/>

</Provider>

);

}

}

module.exports = App;

action纯函数,同时把action type单独写出来。在action同目录下文件types.js

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:36:44

* @modify date 2017-05-17 10:36:44

* @desc [description]

*/

'use strict';

//首页 正在上映

export const HOTSHOW_BANNER = 'HOTSHOW_BANNER';

export const HOTSHOW_LIST = 'HOTSHOW_LIST';

export const HOTSHOW_FETCH = 'HOTSHOW_FETCH';

export const ADDMORE = 'AddMORE';

hotshow-action.js
/**

* @author ling

* @email [email protected]

* @create date 2017-05-12 04:56:43

* @modify date 2017-05-12 04:56:43

* @desc [description]

*/

import { HOTSHOW_BANNER, HOTSHOW_LIST, HOTSHOW_FETCH, ADDMORE } from './types';

import { hotshowFetch } from '../middleware/index-api';

export const addBanner = (data) => {

return {

type: HOTSHOW_BANNER,

data

}

}

//加载等待,true 显示 反之

export const fetchLoading = (bool) => {

return {

type: HOTSHOW_FETCH,

bool

}

}

export const addList = (data) => {

return {

type: HOTSHOW_LIST,

data

}

}

// 正在热映 初始请求

export const initHotshow = () => {

return hotshowFetch(addList);

}


allReducers.js 整合所有reducer

import { combineReducers } from 'redux';

import { HotShowList, Banner, fetchLoading } from './hotshow/reducers'

const allReducers = combineReducers({

hotshows: HotShowList, // 首屏数据列表 listview

banner: Banner, // 轮播

fetchload: fetchLoading, //加载中boo

});

export default allReducers;


hotshowreducer

/**

* @author ling

* @email [email protected]

* @create date 2017-05-12 04:56:34

* @modify date 2017-05-12 04:56:34

* @desc [description]

*/

import { HOTSHOW_BANNER, HOTSHOW_LIST, HOTSHOW_FETCH } from '../../actions/types';

export const HotShowList = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_LIST:

return Object.assign(

{} , state , {

data : action.data

});

default:

return state;

}

}

export const Banner = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_BANNER:

let subjects = action.data;

let data = subjects.slice(0, 5);// 前五个

return Object.assign(

{} , state , {

data : data

});

default:

return state;

}

}

export const fetchLoading = (state = {}, action) => {

switch (action.type) {

case HOTSHOW_FETCH:

return Object.assign(

{} , state , {

data : action.bool

});

default:

return state;

}

}


api 数据请求

/**

* @author ling

* @email [email protected]

* @create date 2017-05-16 08:34:36

* @modify date 2017-05-16 08:34:36

* @desc [description]

*/

//const hotshow = 'https://api.douban.com/v2/movie/in_theaters';

// const sonshow = 'https://api.douban.com/v2/movie/coming_soon';

// const usshow = 'https://api.douban.com/v2/movie/us_box';

// const nearcinemas = 'http://m.maoyan.com/cinemas.json';

const hotshow = 'http://192.168.×.9:8080/weixin/hotshow.json';

const sonshow = 'http://192.168.×.9:8080/weixin/sonshow.json';

const usshow = 'http://192.168.×.9:8080/weixin/usshow.json';

const nearcinemas = 'http://192.168.×.9:8080/weixin/nearcinemas.json';

import { initHotshow, fetchLoading } from '../actions/hotshow-action';

export function hotshowFetch(action) {

return (dispatch) => {

fetch(hotshow).then(res => res.json())

.then(json => {

dispatch(action(json));

dispatch(fetchLoading(false));

}).catch(msg => console.log('hotshowList-err '+ msg));

}

}


containers\hotshow\index

/**

* @author ling

* @email [email protected]

* @create date 2017-05-17 10:44:56

* @modify date 2017-05-17 10:44:56

* @desc [description]

*/

import React, { Component } from 'react';

import { View, ScrollView } from 'react-native';

import { bindActionCreators } from 'redux';

import { connect } from 'react-redux';

import { size } from '../../util/style';

import HotShowList from './hotshow-list';

import Loading from '../../compoments/comm/loading'

import { fetchLoading, initHotshow } from '../../actions/hotshow-action';

class hotshow extends Component {

componentWillMount() {

let _that = this;

let time = setTimeout(function(){

//请求数据

_that.props.initHotshowAction();

clearTimeout(time);

}, 1500);

}

render() {

return (<View >

{this.props.fetchbool ? <Loading/> : <HotShowList/> }

</View>);

}

}

function mapStateToProps(state) {

return {

fetchbool: state.fetchload.data,

hotshows: state.hotshows.data

}

}

function macthDispatchToProps(dispatch) {

return bindActionCreators({

initHotshowAction: initHotshow,

}, dispatch);

}

export default connect(mapStateToProps, macthDispatchToProps)(hotshow);

BannerCtn 轮播用的swiper 插件, 但swiper加入 listview 有个bug就是图片不显示,结尾做答
import React, { Component } from 'react';

import { Text, StyleSheet, View, Image } from 'react-native';

import { connect } from 'react-redux';

import { bindActionCreators } from 'redux';

import Swiper from 'react-native-swiper';

import { addBanner } from '../../actions/hotshow-action';

import { size } from '../../util/style';

class BannerCtn extends Component {

render() {

let data = this.props.banner.data;

return (

<View style={{height: 200}}>

{ data !== undefined ?

<Swiper height={200} autoplay={true}>

{

data.map((item, i) => {

return ( <View key={i} style={{flex: 1, height:200}}>

<Image style={{flex: 1}} resizeMode='cover'

source={{uri: item.images.large}}/>

<Text style={style.title}> {item.title} </Text>

</View>)

})

}

</Swiper>: <Text>loading</Text>

}

</View>

);

}

}

function mapStateToProps(state) {

return {

banner: state.banner

}

}

let style = StyleSheet.create({

title: {

position: 'absolute',

width: size.width,

bottom: 0,

color: '#ffffff',

textAlign: 'right',

backgroundColor: 'rgba(230,69,51,0.25)'

}

})

export default connect(mapStateToProps)(BannerCtn);

hotshow-list

import React, { Component } from 'react';

import { Text, View, ListView, StyleSheet } from 'react-native';

import { connect } from 'react-redux';

import { bindActionCreators } from 'redux';

import { addBanner } from '../../actions/hotshow-action';

import Loading from '../../compoments/comm/loading';

import Item from '../../compoments/hotshow/item';

import Banner from './banner-ctn';

import Foot from '../../compoments/comm/foot';

class HotShowList extends Component {

constructor(props) {

super(props);

}

componentWillMount() {

//顶部轮播

let { hotshows, bannerAction } = this.props;

let subs = hotshows.data.subjects;

bannerAction(subs);

}

_renderList() {

let { hotshows } = this.props;

let ary = hotshows.data.subjects, subsAry = [], row=[];

row.push(<Banner/>);

for(let i = 0, item; item = ary[i++];) {

//一行两个

subsAry.push(

<Item key={i} rank={i} data={item}/>

);

if(subsAry.length == 2) {

row.push(subsAry);

subsAry = [];

}

}

return row;

}

_renderRow(data) {

return(

<View style={{marginTop: 1, flexWrap:'wrap', flexDirection: 'row', justifyContent: 'space-between'}}>{data}</View>

);

}

render() {

let ds = new ListView.DataSource({

rowHasChanged: (r1, r2) => r1 !== r2

});

let data = this._renderList();

this.state = {

dataSource: ds.cloneWithRows(data),

}

//removeClippedSubviews 处理 banner 图片不显示

return (

<View>

<View>

<ListView removeClippedSubviews={false} dataSource={this.state.dataSource} renderRow={this._renderRow}/>

</View>

<Foot/>

</View>

);

}

}

function mapStateToProps(state) {

return {

hotshows: state.hotshows

}

}

function macthDispatchToProps(dispatch) {

return bindActionCreators({ bannerAction: addBanner}, dispatch);

}

let style = StyleSheet.create({

listbox: {

marginBottom: 45,

}

});

export default connect(mapStateToProps, macthDispatchToProps)(HotShowList);

剩下 便是foot tab 和单个item的编写

/**

* @author ling

* @email [email protected]

* @create date 2017-05-19 08:38:19

* @modify date 2017-05-19 08:38:19

* @desc [description]

*/

import React, { Component } from 'react';

import { Text, View, Image, StyleSheet } from 'react-native';

import { size } from '../../util/style';

const width = size.width/2-0.2;

class item extends Component{

render() {

let data = this.props.data;

return(

<View style={style.box}>

<Image resizeMode='cover' style={style.avatar} source={{uri:data.images.large}}/>

<View style={style.rank}>

<Text style={style.rankTxt}>Top{this.props.rank}</Text>

</View>

<View style={style.msgbox}>

<View style={style.msgrow}>

<Text style={style.msgrowl}>{data.title}</Text>

<Text style={style.msgrowr}>评分:{data.rating.average}</Text>

</View>

<View style={style.msgrow}>

<Text style={style.msgrowl}>

{data.genres.map((item, i)=> {

if(i > 1) return;

i == 1 ? null : item += ',';

return item;

})}

</Text>

<Text style={style.msgrowr}>观影人数:{data.collect_count}</Text>

</View>

</View>

</View>

);

}

}

let style = StyleSheet.create({

box: {

width: width,

paddingBottom: 1

},

avatar: {

flex: 1,

height: 260,

},

rank: {

position: 'absolute',

top: 0,

left: 0,

backgroundColor: 'rgba(255,164,51,0.6)',

paddingVertical: 1,

paddingHorizontal: 3,

borderBottomRightRadius: 4

},

rankTxt: {

fontSize: 12,

color: '#ffffff'

},

msgbox: {

position: 'absolute',

bottom: 1,

width: width,

paddingHorizontal: 2,

backgroundColor: 'rgba(230,69,51,0.5)',

},

msgrow: {

flex: 1,

flexDirection: 'row',

justifyContent: 'space-between',

},

msgrowl: {

fontSize: 12,

color: '#ffffff'

},

msgrowr: {

fontSize: 13,

color: '#ffffff'

}

});

module.exports = item;


到此一个react-native 配合redux 编程首屏显示就大体完成了,

Swiper Image 在ListView不显示在,解决如下,测试手机微android

4.4.4,有把react-native升级为0.44.2 亲测无效

    constructor(props) {

super(props);

this.state={

visibleSwiper: false

}

}

render() {

let data = this.props.banner.data;

return (

<View style={{height: 200}}>

{ this.state.visibleSwiper ?

<Swiper/>: <Text>LOADING</Text>

}

</View>

);

}

componentDidMount() {

let time = setTimeout(() => {

this.setState({

visibleSwiper: true

});

clearTimeout(time);

}, 200);

}

关于初始ajax数据,可以在create store的时候获取数据构建初始状态,也可以在ComponentDidMount的时候去执行action发ajax,

上文写错了,github 纠正

github:

https://github.com/helloworld3q3q/react-native-redux-demo

有需要的交流的可以加个好友




以上是 react-native,react-redux和redux配合开发 的全部内容, 来源链接: utcz.com/z/383890.html

回到顶部