Part One
Image组件的自带属性
Part Two
自定义组件并添加属性
上面的贴图中我们总结了组件属性的使用和赋值,在JSX语法中给属性赋值,值一般都是对象。比如上面的source={pic}。下面我们就来自定义一个组件并指定一个属性为name。
import React, { Component } from 'react';
import {
Text } from 'react-native';
/**
* 下面我们自定义一个组件Greeting 并指定一个属性名为name
*/
class Greeting extends Component {
render() {
return (
// this.props.name 说明我们指定的是一个Props,名字是name
<Text>Hello {this.props.name}!</Text>
);
}
}
上面的代码中我们创建了一个名为Greeting的组件并创建一个名为name的属性,属性通过this.props.name指定。上面的这个例子中我们在自定义组件中的render()函数中引用this.props是因为这个组件是用于展示文字用的,写在render()函数中也是为了能直接渲染在屏幕上。
使用自定义组件并给属性赋值
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View
} from 'react-native';
class LotsOfGreetings extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
// 注意下面的这个属性赋值的时候没有用{}括起来,是因为字符串背身就是一个对象,''标识JavaScript是支持的,外面加上{}也是一样的,比如最后加上一行
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
<Greeting name={'Valeera'} />
</View>
);
}
}
AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);
官网的示例代码中Greeting组件和LotsOfGreetings 组件是在同一个js文件中的,这样来对于刚入门的程序员来说看着可能会简单一些,但是你要知道不管怎么说你也是程序员,看着那么长的文件,一点都不清晰,所以即便你是新手也去养成好的编程习惯,代码拆分、分层,复用起来也方便代码也整洁清晰。下面我们简单的拆分一下。为了程序员的’尊严’我们按照如下操作去拆分js文件,并达到预期的效果:
第一步:
我们将Greeting组件的js文件命名为Greeting.js 并放在index.android.js文件所在目录。
第二步:
在Greeting.js文件的末尾加上下面这句:
module.exports = Greeting;
第三步:
在LotsOfGreetings所在的js文件中加入下面的一行代码:(也就是在需要使用我们的Greeting的地方使用下面的代码),然后在文件中对应使用就行了,注意是Props还是State
var Greeting = require('./Greeting');
// ES6写法
// let Greeting = require('./Greeting');
注:因为我们是新添加了js文件,所以一定要重新编译项目并运行才行,运行命令:react-native run-android
下面是完整代码:
Greeting.js文件内容:
import React, { Component } from 'react';
import {
Text } from 'react-native';
/**
* 下面我们自定义一个组件Greeting 并指定一个属性名为name
*/
class Greeting extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
/*
* 下面这是最重要的一行
*/
module.exports = Greeting;
LotsOfGreetings.js文件内容:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View
} from 'react-native';
// 使用自定义的组件
let Greeting = require('./Greeting');
class LotsOfGreetings extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
</View>
);
}
}
AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);
Part Three
上面说了一下Props,顺便也说了一下怎么引用自定义组件,现在回顾一下,引用组件最重要的就是把组件暴露出来,使用到的代码是:module.exports = Gretting;
其次就是在引用的时候使用的代码是:let Blink = require('./Greeting');
其实React官方推荐写法是将自定义组件通过一个js文件去同意管理,也就是会提供一个main.js文件去管理我们自定义的组件。一般main.js文件内容如下:
var Component = {
自定义组件1:require('./BorderBtn/BorderBtn');
自定义组件2:require('./YYNewTopBar/YYNewTopBar');
}
// 然后把main.js中管理我们自定义组件的Component暴露出去
module.exports = Component;
Part Four
上面说了Props,下面我们来说一下State,引用官方文档的一句话:Props和State来控制一个组件,Props是在父组件中指定(在Java中其实就是类中的属性),而且一经指定,在被指定的组件的生命周期中则不再改变。对于需要改变的数据,我们需要使用State。
其实React框架将所有的UI视为一个简单的状态机,当这个状态机的状态发生改变的时候,默认的界面就会更新,这样的话我们就可以很轻松的实现数据发生变化时UI的更新(其实意思就是我们可以直接在独立的组件中通过不同的State来控制数据变化是UI的更新)。
下面我们就以官网中的例子来总结一下RN中的State:
// 这也是一个index.android.js文件。这里我们就不拆分这个JS文件了,直接分析这个示例
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Blink extends Component {
constructor(props) {
super(props);
// 这里定义一个state名为showText默认值是true
this.state = { showText: true };
// 每1000毫秒对showText状态做一次取反操作,相当于一个定时器
setInterval(() => {
this.setState({ showText: !this.state.showText });
}, 1000);
}
render() {
// 根据当前showText的值决定是否显示text内容,这行代码相当于Java中的三目运算
let display = this.state.showText ? this.props.text : ' ';
return (
// 这里通过一个变量去显示一个属性text,通过上面的this.props.text来指定具体显示的是什么内容,和上面的例子相比就是通过定义了一个变量的方式接收了一下这个属性值而已
<Text>{display}</Text>
);
}
}
class BlinkApp extends Component {
render() {
return (
// 使用组件 并 给属性text赋值
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
AppRegistry.registerComponent('BlinkApp', () => BlinkApp);
上面就是组件的State–状态,一般状态的改变通常会去更新UI。官网中的说法:在实际开发中,我们一般不会在定时器函数(setInterval、setTimeout等)中来操作state。典型的场景是在接收到服务器返回的新数据,或者再用户输入数据后才会去操作state。当然,你也可以使用一些“状态容器”比如Redux来统一管理数据流(译注:但我们不建议新手过早的去学习Redux)。
注:写到现在大家应该也能发现,在Component中一般都会重写render()函数,因为一个组件肯定是有对应的UI展示的,所以一般都会重写render()函数。