RN学习

 

一.  第一个应用: 天气小应用

import React, { Component } from "react";

import { StyleSheet, Text, View, TextInput, ImageBackground } from "react-native";

import Forecast from "./Forecast";
import OpenWeatherMap from "./open_weather_map";

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = { zip: "", forecast: null };
  }

  _handleTextChange = event => {
    let zip = event.nativeEvent.text;
    OpenWeatherMap.fetchForecast(zip).then(forecast => {
      this.setState({ forecast: forecast });
    });
  };

  render() {
    let content = null;
    if (this.state.forecast !== null) {
      content = (
        <Forecast
          main={this.state.forecast.main}
          description={this.state.forecast.description}
          temp={this.state.forecast.temp}
        />
      );
    }
    return (
      <View style={styles.container}>
        <ImageBackground
          source={require("./flowers.png")}
          resizeMode="cover"
          style={styles.backdrop}
        >
          <View style={styles.overlay}>
            <View style={styles.row}>
              <Text style={styles.mainText}>
                Current weather for
              </Text>
              <View style={styles.zipContainer}>
                <TextInput
                  style={[styles.zipCode, styles.mainText]}
                  onSubmitEditing={this._handleTextChange}
                  underlineColorAndroid="transparent"
                />
              </View>
            </View>
            {content}
          </View>
        </ImageBackground>
      </View>
    );
  }
}

const baseFontSize = 16;

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: "center", paddingTop: 30 },
  backdrop: { width:"100%",height:"100%" },
  overlay: {paddingTop: 5,
    backgroundColor: "#000000",
    opacity: 0.5,
    flexDirection: "column",
    alignItems: "center"
  },
  row: {
    flexDirection: "row",
    flexWrap: "nowrap",
    alignItems: "flex-start",
    padding: 30
  },
  zipContainer: {
    height: baseFontSize + 10,
    borderBottomColor: "#DDDDDD",
    borderBottomWidth: 1,
    marginLeft: 5,
    marginTop: 3
  },
  zipCode: { flex: 1, flexBasis: 1, width: 50, height: baseFontSize },
  mainText: { fontSize: baseFontSize, color: "#FFFFFF" }
});

export default WeatherProject;

1.event.nativeEvent.text  

(1)onChange:当文本发生变化时,调用该函数。

  • 它的回调接收一个 event 参数,通过 event.nativeEvent.text 可以获取用户输入的字符串。

(2)onEndEditing:当结束编辑时,调用该函数。

  • 它的回调接收一个 event 参数,通过 event.nativeEvent.text 可以获取用户输入的字符串。

 

(3)onBlur:失去焦点时触发(在 onEndEditing 之后)。

  • 它的回调接收一个 event 参数,通过 event.nativeEvent.text 可以获取用户输入的字符串。

 

(4)onFocus:获得焦点时触发。

  • 它的回调接收一个 event 参数,通过 event.nativeEvent.text 可以获取组件中的字符串(上次输入的,或者是程序设定的默认值)

 

(5)onSubmitEditing:当结束编辑后,点击键盘的提交按钮触发该事件。

  • 它的回调接收一个 event 参数,通过 event.nativeEvent.text 可以获取用户输入的字符串。

 

2.{ width:"100%",height:"100%" }   宽高占页面的100%

 

 

 

 

二.

1.split() 方法用于把一个字符串分割成字符串数组。
  str.split(' ' );是以空格拆分,差分后,行程结果的数组,数组的元素都为字符串。
  str.split(' ',3); 是以空格拆分,拆分后,只取数组length为3的数组。
例如: this.state.text.split('#')[this.state.text.split('#').length - 1] 用 ‘#’ 字符拆分字符串,并取得数组的最后一个元素

2.map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。

3.运算符 &&   || 
在运算过程中,首先js 会将 && 和|| 两边的值转成Boolean 类型,然后再算值 ,
&&运算如果返回true,则取后面的值,如果|| 返回true,则取前面的值 ,
而其中数值转换成boolean 的规则 是:  对象、非零整数、非空字符串返回true,其它为false ;
例如:该逻辑运算符支持短路原则 参考:http://blog.csdn.net/xiaoshuode/article/details/51612423
 var a = “” || null || 3 || 4 —-> var a = false || false || true || true 结果为true 则返回第一个true,即是3
分析: ||  这个运算符 “一真为真”,结果返回true,取前面的true(第一个true),即是 3
var b = 4 && 5 && null && 0 ——> var b = true && true && false && false 结果是false 则返回第一个false 即是null .
分析: && 这个运算符  “一假为假”,结果返回false,取前面的false(第一个false),即是 null
var c = 5 && 6 ----->var c =  true && true 结果为ture,则返回后面的ture,即是 6
5.join() 方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。
 语法
 arrayObject搜索.join(separator)
 参数、描述
 separator    可选。指定要使用的分隔符。如果省略该参数,则默认使用逗号作为分隔符。
 返回值
 返回一个字符串。该字符串是通过把 arrayObject 的每个元素转换为字符串,然后把这些字符串连接起来,在两个元素之间插入separator 字
符串而生成的。

 

 

三.  react-navigation

// In App.js in a new project 
import React from "react"; 
import {  Button,View, Text } from "react-native"; 
import { createStackNavigator, createAppContainer } from "react-navigation"; 



class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
        <Text>Details Screen</Text>
      </View>
    );
  }
}
   class HomeScreen extends React.Component {
    render() {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Details"
            onPress={() => this.props.navigation.navigate('Details')}
          />
        </View>
      );
    }
  }

  

const AppNavigator = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailsScreen
  },
  {
    initialRouteName: "Home"
  }
);
   
const AppContainer = createAppContainer(AppNavigator);

export default class App extends React.Component {
  render() {
    return <AppContainer />;
  }
}

1.  每个页面可用一个class定义  ,class名为路由到的名字(键值对中的值),   而navigate方法调用的为键值对中的键

2.this.props.navigation.navigate('RouteName') `将新路由推送到堆栈导航器,如果它尚未在堆栈中,则跳转到该页面。

3.使用` this.props.navigation.popToTop() `返回堆栈中的第一个页面。

4.生命周期??????

5.传递参数

<Button
          title="Go to Details... again"
          onPress={() =>
            this.props.navigation.navigate('Details', {
              itemId: 86,
              otherParam: 'anything you want here',
            })}
        />

6.读取参数

const otherParam = navigation.getParam('otherParam', 'some default value');

第一个参数是要读的值,第二个参数是缺省值

你也可以直接使用this.props.navigation.state.params访问 params 对象。 如果没有提供参数,这可能是null,所以使用getParam通常更容易,所以你不必处理这种情况。

 

(2)

设置标题栏显示的标题

每个页面组件可以有一个名为navigationOptions的静态属性,它是一个对象或一个返回包含各种配置选项的对象的函数。 我们用于设置标题栏的标题的是title这个属性,如以下示例所示。

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
  };

  /* render function, etc */
}

class DetailsScreen extends React.Component {
  static navigationOptions = {
    title: 'Details',
  };

  /* render function, etc */
}

在标题中使用参数

为了在标题中使用参数,我们需要使navigationOptions成为一个返回配置对象的函数。 尝试在navigationOptions中使用this.props可能很诱人,但因为它是组件的静态属性,所以this不会指向一个组件的实例,因此没有 props 可用。 相反,如果我们将navigationOptions作为一个函数,那么React Navigation将会用包含{navigation> navigationOptions,screenProps}的对象调用它 -- 在这种情况下,我们只用关心navigation,它是与传递给页面的this.props.navigation </ code>相同的对象。 您可能还记得,我们可以通过<code> navigation.state.paramsnavigation中获取参数,因此我们执行下面的操作以提取 param 并将其用作标题。

class DetailsScreen extends React.Component {
  static navigationOptions = ({ navigation }) => {
    return {
      title: navigation.getParam('otherParam', 'A Nested Details Screen'),
    };
  };

  /* render function, etc */
}

 

 

 

 

跨页面共享通用的navigationOptions

通常我们希望可以在多个页面上以类似的方式配置标题栏。 例如,你公司的品牌颜色可能为红色,因此你希望标题栏背景颜色为红色,色调为白色。 方便的是,这些只是我们正在使用的运行示例的颜色,并且你会注意到,当你导航到DetailsScreen时,颜色会恢复默认值。 如果在我们应用中每个页面上,都必须,像将navigationOptions的标题栏样式属性从HomeScreen复制到DetailsScreen一样,那是不是非常的糟糕? 谢天谢地,我们并没有这么做。 我们可以将配置移动到` defaultNavigationOptions </ code>属性下的 stack navigator 中。

const RootStack = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
},
{
initialRouteName: 'Home',
/* The header config from HomeScreen is now here */
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
}
);
`

 

覆盖共享的navigationOptions

你的页面组件上指定的navigationOptions与其父级 stack navigator 中的navigationOptions一起合并时,页面组件上的选项优先。 让我们使用这些知识点在Details页面上反转背景和色彩。

 

使用自定义组件替换标题

有时候,你可能需要更多的控制权,而不仅仅是改变标题的文本和样式 -- 例如,你可能想在标题所在的位置放置一张图片,或者将标题变为按钮。 在这些情况下,你可以完全覆盖用于标题的组件并提供您自己的组件。

class LogoTitle extends React.Component {
  render() {
    return (
      <Image
        source={require('./spiro.png')}
        style={{ width: 30, height: 30 }}
      />
    );
  }
}

class HomeScreen extends React.Component {
  static navigationOptions = {
    // headerTitle instead of title
    headerTitle: <LogoTitle />,
  };

  /* render function, etc */
}

您可能想知道,为什么headerTitle能够支持我们设置一个组件,而不是像以前一样设置一个title? 原因是headerTitle是一个特定于 stack navigator 的属性,headerTitle默认为一个Text组件,它显示title这个字符串。

 

标题栏和其所属的页面之间的交互

最常用的模式是在组件实例上提供按钮访问函数 params。 我们将用一个经典的例子--计数器,来演示:

 

class HomeScreen extends React.Component {
  static navigationOptions = ({ navigation }) => {
    return {
      headerTitle: <LogoTitle />,
      headerRight: (
        <Button
          onPress={navigation.getParam('increaseCount')}
          title="+1"
          color="#fff"
        />
      ),
    };
  };

  componentDidMount() {
    this.props.navigation.setParams({ increaseCount: this._increaseCount });
  }

  state = {
    count: 0,
  };

  _increaseCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  /* later in the render function we display the count */
}

 

 

import React from 'react';
import { Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Home!</Text>
      </View>
    );
  }
}

class SettingsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Settings!</Text>
      </View>
    );
  }
}

const TabNavigator = createBottomTabNavigator({
  Home: HomeScreen,
  Settings: SettingsScreen,
},
{
  defaultNavigationOptions: ({ navigation }) => ({
    tabBarIcon: ({ focused, horizontal, tintColor }) => {
      const { routeName } = navigation.state;
      let IconComponent = Ionicons;
      let iconName;
      if (routeName === 'Home') {
        iconName = `ios-information-circle${focused ? '' : '-outline'}`;
        // Sometimes we want to add badges to some icons. 
        // You can check the implementation below.
        IconComponent = HomeIconWithBadge; 
      } else if (routeName === 'Settings') {
        iconName = `ios-options`;
      }

      // You can return any component that you like here!
      return <IconComponent name={iconName} size={25} color={tintColor} />;
    },
  }),
  tabBarOptions: {
    activeTintColor: 'tomato',
    inactiveTintColor: 'gray',
  },
}
);

export default createAppContainer(TabNavigator);

 

 

 

  • tabBarIconnavigationOptions上的一个属性,所以我们知道我们可以在我们的页面上使用它,但在这种情况下,选择将它放在createBottomTabNavigator的配置中,是为了方便集中配置图标。
  • tabBarIcon 是一个给定focused state、tintColor和 horizontal 等参数的函数 如果你在配置中进一步查看,您将看到tabBarOptionsactiveTintColorinactiveTintColor。 这些默认为 iOS 平台的默认值,但您可以在这里更改它们。 传递给tabBarIcontintColor取决于focused这个 state (判断该 Tab 是否获得了焦点),可以是活动,也可以是非活动状态。 当设备处于横屏时,horizontal 是 true;否则就是false
  • 有关createBottomTabNavigator配置选项的更多信息,请阅读完整API参考

 

四.  一些反复出现的问题

(1) 箭头函数

x => x * x

上面的箭头函数相当于:

function (x) {
    return x * x;
}

 

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }return都省略掉了。还有一种可以包含多条语句,这时候就不能省略{ ... }return

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

如果参数不是一个,就需要用括号()括起来:

// 两个参数:
(x, y) => x * x + y * y

// 当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}

// 无参数:
() => 3.14

// 可变参数:
(x, y, ...rest) => {
    var i, sum = x + y;
    for (i=0; i<rest.length; i++) {
        sum += rest[i];
    }
    return sum;
}

如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:

// SyntaxError:
x => { foo: x }

因为和函数体的{ ... }有语法冲突,所以要改为:

// ok:
x => ({ foo: x })

 

(2) this

先理解普通JavaScript 的this 事件

  • 当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象
  • 当函数被一个对象“包含”的时候,我们称函数的this被隐式绑定到这个对象里面了,这时候,通过this可以直接访问所绑定的对象里面的其他属性,比如下面的a属性
var obj = { a:1,
    fire:function() {
           console.log(this.a)
            }}

obj.fire();      //输出1

// fire函数并不会因为它被定义在obj对象的内部和外部而有任何区别,也就是说在上述隐式绑定的两种形式下,fire通过this还是可以访问到obj内的a属性,这告诉我们:this是动态绑定的,或者说是在代码运行期绑定而不是在书写期

function
fire () {
      console.log(this.a)
}
  

var obj = {a:1,fire:fire }

obj.fire();   //  输出1
  • 2. 函数于对象的独立性, this的传递丢失问题

    隐式绑定下,作为对象属性的函数,对于对象来说是独立的(

    在上文中,函数虽然被定义在对象的内部中,但它和“在对象外部声明函数,然后在对象内部通过属性名称的方式取得函数的引用”,这两种方式在性质上是等价的(而不仅仅是效果上)

    定义在对象内部的函数只是“恰好可以被这个对象调用”而已,而不是“生来就是为这个对象所调用的”)

var obj = { a:1,    //a是定义在对象obj中的属性   1
    fire:function() {
        console.log(this.a)}
            }

  var

a = 2;  //a是定义在全局环境中的变量    2

var fireInGrobal = obj.fire;  
fireInGrobal();  // 输出 2    这个于obj中的fire函数的引用( fireInGrobal)在调用的时候,行为表现(输出)完全看不出来它就是在obj内部定义的,其原因在于:我们隐式绑定的this丢失了!! 从而 fireInGrobal调用的时候取得的this不是obj,而是window

3.在一串对象属性链中,this绑定的是最内层的对象

 

 

 

所以根据以上可知,由于JavaScript函数对this绑定的错误处理,下面的例子无法得到预期结果:

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window或undefined
        };
        return fn();
    }
};

ES6的箭头函数,这里可以看出箭头函数中访问的this实际上是其父级作用域中的this(箭头函数相当于一个function,看箭头函数上一个function然后相当于正常的this理解),箭头函数本身的this是不存在的,这样就相当于箭头函数的this是在声明的时候就确定了(因为相当于作用域嘛)

var obj = {
        age: 1,
        say: function() {
            setTimeout(function() {
                console.log(this, this.age); // window undefined
            }, 0);
        },
    }

    var obj1 = {
        age: 1,
        say: function() {
            setTimeout(() => {
                console.log(this, this.age); // obj1 1
            }, 0);
        }
    };



var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b(); 
// undefined, Window{...}
obj.c(); 
// 10, Object {...}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值