项目地址为:https://github.com/ImVeryGood/RNNewsGo

我们先来看一下页面

分析了一下项目,项目也是有用到redux-saga的

然后模块比较清晰

接下来我们分析代码

//index.js
/**
* @format
*/ import { AppRegistry } from "react-native";
import App from "./App";
import { name as appName } from "./app.json"; AppRegistry.registerComponent(appName, () => App);

根index.js引用的是根App.js

固定的可切换底部

//src/screens/base/Navigations.js
import {
createAppContainer,
createBottomTabNavigator,
createStackNavigator
} from "react-navigation";
import { Image, StyleSheet } from "react-native";
import News from "../news/News";
import React from "react";
import Mine from "../mine/Mine";
import Picture from "../picture/Picture";
import Video from "../video/Video";
import TopNavigation from "../picture/components/TopNavigation";
const tabBottom = createBottomTabNavigator(
{
News: {
screen: News,
navigationOptions: {
header: null,
tabBarLabel: "新闻",
tabBarIcon: ({ focused }) => {
return (
<Image
style={styles.tabBarIcon}
source={
focused
? require("./image/b_newhome_tabbar_press.png")
: require("./image/b_newhome_tabbar.png")
}
/>
);
}
}
},
Picture: {
screen: Picture,
navigationOptions: {
header: null,
tabBarLabel: "图片",
tabBarIcon: ({ focused }) => {
return (
<Image
style={styles.tabBarIcon}
source={
focused
? require("./image/b_newcare_tabbar_press.png")
: require("./image/b_newcare_tabbar.png")
}
/>
);
}
}
},
Video: {
screen: Video,
navigationOptions: {
header: null,
tabBarLabel: "视频",
tabBarIcon: ({ focused }) => {
return (
<Image
style={styles.tabBarIcon}
source={
focused
? require("./image/b_newdiscover_tabbar_press.png")
: require("./image/b_newdiscover_tabbar.png")
}
/>
);
}
}
},
Mine: {
screen: Mine,
navigationOptions: {
header: null,
tabBarLabel: "我的",
tabBarIcon: ({ focused }) => {
return (
<Image
style={styles.tabBarIcon}
source={
focused
? require("./image/b_newmine_tabbar_press.png")
: require("./image/b_newmine_tabbar.png")
}
/>
);
}
}
}
},
{
initialRouteName: "News",
swipeEnabled: true,
indicatorStyle: { height: 0 },
tabBarOptions: {
//当前选中的tab bar的文本颜色和图标颜色
activeTintColor: "red",
//当前未选中的tab bar的文本颜色和图标颜色
inactiveTintColor: "#000"
}
}
);
const App = createStackNavigator({
Main: {
screen: tabBottom,
navigationOptions: {
header: null,
indicatorStyle: { height: 0 }
}
}
}); export default createAppContainer(App);
const styles = StyleSheet.create({
tabBarIcon: {
width: 30,
height: 30
}
});
//App.js
import React, { Component } from "react";
//固定的底部切换
import Navigations from "./src/screens/base/Navigations";
import { Provider } from "react-redux";
//有用到数据持久化
import { store, persistor } from "./src/store/configStore";
import { PersistGate } from "redux-persist/integration/react";
import { Router } from "react-native-router-flux";
import scenes from "./src/scenes";
type Props = {};
export default class App extends Component<Props> {
onBeforeLift = () => {
// take some action before the gate lifts
};
render() {
return (
<Provider store={store}>
<PersistGate persistor={persistor} loading={this.onBeforeLift()}>
<Navigations />
</PersistGate>
</Provider>
);
}
}

接下来是切换时对应的每一个tab的页面

新闻页面

//src/screens/news/News.js
//newsaction里面没有什么内容
import { actionTypes } from "./actionTypes"; const getNewsData = () => {
return {
type: actionTypes.NEWS
};
};
export const news_action = {
getNewsData
};
//src/saga/news_saga.js
import {
put,
call,
takeLatest,
takeEvery,
fork,
take,
select
} from "redux-saga/effects";
import "whatwg-fetch";
import { actionTypes } from "../action/actionTypes";
import fetchSmart from "../service/fetch";
import { urlMap } from "../service/UrlMap";
function* getNews() {
while (true) {
yield take(actionTypes.NEWS);
// fetchSmart(urlMap.bannerUrl)
// .then(response => {
// alert(response);
// })
// .catch(error => {
// alert(error);
// });
fetch(urlMap.news_url, {
method: "GET",
headers: { Connection: "true" }
})
.then(response => response.json())
.then(data => console.log("AAAAAdata is", data))
.catch(error => console.log("AAAAAerror is", error));
yield put({
type: actionTypes.NEWS_SAGA,
news_saga: Math.random(100 - 1)
});
}
}
export default function* root(): any {
yield fork(getNews);
}

点击进入图片



也是对里面的内容进行了模块的封装

//src/screens/picture/Picture.jsimport React from "react";
import { View, Button, Text, Image, StyleSheet, FlatList } from "react-native";
import { bindActionCreators } from "redux";
import index_action from "../../action/index_action";
import { connect } from "react-redux";
import TobNavigation from "./components/TopNavigation"; class Picture extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
_navigationStateChange = index => {
this.props.actions.getRecommend(index);
};
render() {
return (
<TobNavigation
onNavigationStateChange={(prevState, currentState) => {
this._navigationStateChange(currentState.index);
}}
/>
);
}
} const styles = StyleSheet.create({});
const mapStateToProps = state => {
return {};
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators(index_action, dispatch)
};
};
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(Picture);

上面的是在图片目录下可以切换的内容

每一个screen对应的也是单独的页面

//src/screens/picture/components/TopNavigation.js
import { ColorSource } from "../../../sources/ColorSource";
import Recommend from "./Recommend";
import StarPic from "./StarPic";
import NewsPic from "./NewsPic";
import {
createMaterialTopTabNavigator,
createAppContainer
} from "react-navigation";
/**
* createMaterialTopTabNavigator,实现顶部Tab栏的切换
*/
const TobBar = createMaterialTopTabNavigator(
{
Recommend: {
screen: Recommend,
navigationOptions: {
tabBarLabel: "推荐"
}
},
NewsPic: {
screen: NewsPic,
navigationOptions: {
tabBarLabel: "新闻"
}
},
StarPic: {
screen: StarPic,
navigationOptions: {
tabBarLabel: "明星"
}
}
},
{
tabBarOptions: {
//tab bar的位置, 可选值: 'top' or 'bottom'
tabBarPosition: "top",
swipeEnabled: true,
allowFontScaling: true,
scrollEnabled: false,
style: {
backgroundColor: ColorSource.blue //设置顶部tab的背景颜色
},
// 设置下划线的颜色
indicatorStyle: {
backgroundColor: ColorSource.red
},
activeTintColor: ColorSource.red, //设置选中字的颜色
inactiveTintColor: ColorSource.white //设置未选中的颜色样式
},
// style: { backgroundColor: ColorSource.red },
initialRouteName: "Recommend"
}
); export default createAppContainer(TobBar);

这个是recommend组件

//src/screens/picture/components/Recommend.js
//里面也还是有封装
import {
View,
Text,
FlatList,
Button,
Modal,
Image,
StyleSheet,
TouchableWithoutFeedback
} from "react-native";
import React from "react";
import { bindActionCreators } from "redux";
import index_action from "../../../action/index_action";
import { connect } from "react-redux";
import PictureListComponent from "./PictureListComponent";
class Recommend extends React.Component {
constructor(props) {
super(props);
this.state = {
recommend: [],
isShowModule: false,
pic: []
};
}
componentDidMount() {
this.props.actions.getRecommend(0);
}
render() {
const { recommend } = this.props; return (
<View>
<PictureListComponent data={recommend} />
</View>
);
}
}
const styles = StyleSheet.create({});
const mapStateToProps = state => {
return { recommend: state.picture_reducer.get("recommend") };
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators(index_action, dispatch)
};
};
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(Recommend);

接下来进行的就是图片内的组件

这个只是封装的单个的图片组件

//src/screens/picture/components/PictureListComponent.js
import React from "react";
import {
View,
VirtualizedList,
StyleSheet,
ScrollView,
RefreshControl,
Text,
Platform,
FlatList,
TouchableWithoutFeedback,
Image,
Modal
} from "react-native";
import PictureModule from "./PictureModule";
import { ColorSource } from "../../../sources/ColorSource";
type Props = {
data?: Array<any>
};
class PictureListComponent extends React.Component {
constructor(props: Props) {
super(props);
this.state = {
isShowModule: false,
pic: []
};
}
_showPic(item, index) {
this.setState({
isShowModule: !this.state.isShowModule,
pic: item.pics
});
}
_emptyView = () => {
return (
<View style={styles.emptyView}>
<Text>暂无数据</Text>
</View>
);
};
_renderItem = ({ item, index }) => {
return (
<TouchableWithoutFeedback onPress={() => this._showPic(item, index)}>
<View style={styles.item}>
<Image
source={{
uri: item.scover
}}
style={styles.image}
/>
<Text style={styles.name}>{item.setname}</Text>
</View>
</TouchableWithoutFeedback>
);
};
_ModalPic() {
if (this.state.pic.length > 0) {
return (
<Modal
onRequestClose={() => {
this.setState({
isShowModule: false
});
}}
visible={this.state.isShowModule}
>
<PictureModule pic={this.state.pic} />
</Modal>
);
}
}
render() {
return (
<View>
<FlatList
renderItem={this._renderItem}
data={this.props.data}
extraData={this.state}
keyExtractor={(item, index) => index.toString()}
numColumns={1}
ListEmptyComponent={this._emptyView()}
disableVirtualization={true}
/>
{this._ModalPic()}
</View>
);
}
}
const styles = StyleSheet.create({
emptyView: {
flex: 1,
alignItems: "center"
},
item: {
height: 180,
marginBottom: 10
},
name: {
position: "absolute",
marginLeft: "5%",
marginRight: "5%",
height: 50,
lineHeight: 50,
bottom: 0,
width: "90%",
backgroundColor: ColorSource.grey
},
image: {
height: 180,
width: "90%",
marginLeft: "5%",
marginRight: "5%"
}
});
module.exports = PictureListComponent;
//src/screens/picture/components/PictureModule.js
//这个里面的图片是可以点击滑动的意思
import React from "react";
import { View, Image, Text, StyleSheet } from "react-native";
import Swiper from "react-native-swiper";
class PictureModule extends React.Component {
constructor(props) {
super(props);
this.state = {};
} _renderSwiper() {
let itemArr = [];
let dataArr = this.props.pic;
if (dataArr.length > 0) {
for (let i = 0; i < dataArr.length; i++) {
let pic = {
uri: dataArr[i]
};
itemArr.push(<Image source={pic} style={styles.image} />);
}
}
return itemArr;
}
render() {
return (
<Swiper showsPagination={true} showsButtons={true}>
{this._renderSwiper()}
</Swiper>
);
}
}
const styles = StyleSheet.create({
image: {
flex: 1
}
});
module.exports = PictureModule;
//src/screens/picture/components/StarPic.js
//这个都不知道是做什么的~
import { View, Text } from "react-native";
import React from "react";
import { bindActionCreators } from "redux";
import index_action from "../../../action/index_action";
import { connect } from "react-redux";
import PictureListComponent from "./PictureListComponent"; class StarPic extends React.Component {
constructor(props) {
super(props);
} render() {
const { star } = this.props;
return (
<View>
<PictureListComponent data={star} />
</View>
);
}
} const mapStateToProps = state => {
return { star: state.picture_reducer.get("star") };
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators(index_action, dispatch)
};
};
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(StarPic);

//视频页面什么都没有
//src/screens/video/Video.js
import React from "react";
import { View, Button, Text, Image, StyleSheet } from "react-native";
import { bindActionCreators } from "redux";
import index_action from "../../action/index_action";
import { connect } from "react-redux"; class Video extends React.Component {
constructor(props) {
super(props);
} render() {
return <View />;
}
} const styles = StyleSheet.create({});
const mapStateToProps = state => {
return {};
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators(index_action, dispatch)
};
};
module.exports = connect(
mapStateToProps,
mapDispatchToProps
)(Video);

关于我的页面

//src/screens/mine/Mine.js
import React from "react";
import { View, Button, Text, Image, StyleSheet, FlatList } from "react-native";
import { bindActionCreators } from "redux";
import index_action from "../../action/index_action";
import { connect } from "react-redux"; export class Mine extends React.Component {
constructor(props) {
super(props);
} render() {
return <View />;
}
} const styles = StyleSheet.create({});
const mapStateToProps = state => {
return {};
};
const matchDispactchToProps = dispatch => {
return {
actions: bindActionCreators(index_action, dispatch)
};
};
module.exports = connect(
mapStateToProps,
matchDispactchToProps
)(Mine);

看了半天原来数据是在redux-saga里面进行处理的啊

//src/saga/picture_saga.js
import {
put,
call,
takeLatest,
takeEvery,
fork,
take,
select
} from "redux-saga/effects";
import "whatwg-fetch";
import { actionTypes } from "../action/actionTypes";
import fetchSmart from "../service/fetch";
import { urlMap, pic_url } from "../service/UrlMap"; function* getRecommend() {
while (true) {
const action = yield take(actionTypes.RECOMMEND);
const index = action.index;
const url = pic_url[index];
try {
const res = yield call(fetchSmart, url);
if (index === 0) {
yield put({ type: actionTypes.RECOMMEND_SAGA, recommend: res });
} else if (index === 1) {
yield put({ type: actionTypes.NEWS_SAGA, news: res });
} else if (index === 2) {
yield put({ type: actionTypes.STAR_SAGA, star: res });
}
} catch (e) {
alert(e);
}
}
}
export default function* root(): any {
yield fork(getRecommend);
}

【水滴石穿】RNNewsGo的更多相关文章

  1. iOS 开发笔记 -- 各种细枝末节的知识(水滴石穿)

    在此总结整理,遇到的各种的小问题: 1.通过从字典(数组)中取出的NSString的length==0 作为if的判断条件导致的carsh: 由于在字典中通过Key取出值之后直接做了length相关操 ...

  2. 【水滴石穿】react-native-book

    先推荐一个学习的地址:https://ke.qq.com/webcourse/index.html#cid=203313&term_id=100240778&taid=12778558 ...

  3. 【水滴石穿】rnTest

    其实就是一个小的demo,不过代码分的挺精巧的 先放地址:https://github.com/linchengzzz/rnTest 来看看效果 确实没有什么可以说的,不过代码部分还行 先入口文件 / ...

  4. 【水滴石穿】rn_statusbar

    先放项目地址https://github.com/hezhii/rn_statusbar 来看一下效果 咩有感觉很怎么样,看代码 根入口文件 //index.js //看代码我们知道入口是app.js ...

  5. 【水滴石穿】react-native-ble-demo

    项目的话,是想打开蓝牙,然后连接设备 点击已经连接的设备,我们会看到一些设备 不过我这边在开启蓝牙的时候报错了 先放作者的项目地址: https://github.com/hezhii/react-n ...

  6. 【水滴石穿】ReactNative-Redux-Thunk

    老实说,运行出来的项目让人失望,毕竟我想看各种有趣的demo啊- 先放上源码地址:https://github.com/ludejun/ReactNative-Redux-Thunk 我们来一起看看代 ...

  7. 【水滴石穿】mobx-todos

    我觉得代码在有些程序员手里,就好像是画笔,可以创造很多东西 不要觉得创意少就叫没有创意,每天进步一点点,世界更美好 首先源码地址为:https://github.com/byk04712/mobx-t ...

  8. 【水滴石穿】ReactNativeMobxFrame

    项目地址如下:https://github.com/FTD-ZF/ReactNativeMobxFrame 应该可以说的是,项目也只是一个花架子,不过底部的tab稍微改变了 我们一起来看代码 //in ...

  9. 【水滴石穿】react-native-aze

    说个题外话,早上打开电脑的时候,电脑变成彩色的了,锅是我曾经安装的一个chrome扩展,没有经过我的同意开启了 (也许是昨天迷迷糊糊开启了) 上午运行项目都不成功,还以为被黑客攻击了---然后下午就排 ...

随机推荐

  1. Linux实现自动登录

    使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: #!/usr/b ...

  2. JZOJ[5971]【北大2019冬令营模拟12.1】 party(1s,256MB)

    题目 题目大意 给你一棵树,在树上的某一些节点上面有人,要用最小的步数和,使得这些人靠在一起.所谓靠在一起,即是任意两个人之间的路径上没有空的节点(也就是连在一起). N≤200N \leq 200N ...

  3. Gartner首推机密计算:阿里云名列其中

    近日,全球信息技术研究机构Gartner发布了2019年云安全技术成熟度曲线报告(Gartner, Hype Cycle for Cloud Security, 2019, Jay Heiser, S ...

  4. IOS开发之基础oc语法

    类 1.类的定义: 类=属性+方法: -属性代表类的特征 -方法是类能对变化做出的反应 类定义的格式:类的声明和类的实现组成 -接口(类的声明):@interface 类名:基类的名字 .类名首字母要 ...

  5. CentOS 6.5 Apache+SVN配置

    yum -y install subversion #安装SVN svnserve -- version #查看svn版本信息确定是否安装 yum -y install httpd #安装Apache ...

  6. Linq之Sum用法新体会

    1.简单应用,求数组的和,示例: , , , , , , , , , }; double numSum = numbers.Sum(); Console.WriteLine("The sum ...

  7. python在WIN下CMD运行中文乱码及python 2.x python 3.x编码问题

    在CMD中运行python代码时,我们会发现,即使在代码中加入# -*- coding:utf-8 -*- 这段代码,中文仍然会乱码.如下: # -*- coding:utf-8 -*- conten ...

  8. js数组操作方法

    数组的操作方法在js中可谓是诸子百家,各种某乱的方法让人眼花缭乱,有时候就会分不清什么是自带的什么是曾今写的api了 数组的增删 1 . push() , pop()  和 shift() unshi ...

  9. 公司-广告-WPP:WPP

    ylbtech-公司-广告-WPP:WPP WPP集团 (LSE:WPP) (NASDAQ:WPPGY),是世界上最大的传播集团,总部位于英国伦敦.WPP集团拥有 60 多个子公司,主要服务于本地.跨 ...

  10. Git--版本管理的使用及理解

    如果多人合作时,git也是需要中间交换服务器来解决冲突合并,这不还是集中式版本控制吗? 而svn不是也可以将所有源码下载到本机,然后在本机修改,保存在本机上,为什么这个不能说是分布式,提交的时候不也是 ...