zoukankan      html  css  js  c++  java
  • 【水滴石穿】RNNewsGo

    项目地址为: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: {
         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,
         "90%",
        backgroundColor: ColorSource.grey
      },
      image: {
        height: 180,
         "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);
    }
    
  • 相关阅读:
    petshop4.0(转)
    分层依据(转)
    如何让一个函数返回多个值
    谁访问过我的电脑
    博客第一帖!
    开发辅助工具大收集
    VC 通过IHTMLINTEFACE 接口实现网页执行自定义js代码
    vi命令大全
    #include <sys/types.h>
    #include <arpa/inet.h>
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10881634.html
Copyright © 2011-2022 走看看