Props(属性)
大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为 props(属性)。所谓 props,就是属性传递,而且是单向传递的。属性多的时候,可以传递一个对象,这是 ES6 中的语法。
官网给的例子是用现成的一个Image基础组件来解释这个概念的,例子如下:
import React, {Component} from 'react';
import {
Image,
StyleSheet
} from 'react-native';
export default class App extends Component {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={styles.image} />
);
}
}
const styles = StyleSheet.create({
image: {
height:110,
width:193
}
});
当我们创建一个 image 图片的时候,我们可以使用名为 source 的 props 属性去控制这个 image 显示什么图片。
注意 {pic} 外围有一层括号,我们需要用括号来把 pic 这个变量嵌入到 JSX 语句中。括号的意思是括号内部为一个 js 变量或表达式,需要执行后取值。因此我们可以把任意合法的 JavaScript 表达式通过括号嵌入到 JSX 语句中。
自定义的组件也可以使用 props。通过在不同的场景使用不同的属性定制,可以尽量提高自定义组件的复用范畴。只需在render函数中引用 this.props,然后按需处理即可。下面是一个例子:
import React, {Component} from 'react';
import {
Text,
StyleSheet,
View
} from 'react-native';
class Greeting extends Component {
render() {
return (
<View style = {styles.container}>
<Text>Hello {this.props.name}!</Text>
</View>
);
}
}
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems:'center'
},
});
意思就是:自定义了一个名为 Greeting 的组件,然后,属性名为 name,传不同的 name 值,在Text 显示不同的名字。
State(状态)
我们使用两种数据来控制一个组件:props 和 state。props 是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用 state。
一般来说,你需要在 constructor 中初始化 state(译注:这是 ES6 的写法,早期的很多 ES5 的例子使用的是 getInitialState 方法来初始化 state,这一做法会逐渐被淘汰),然后在需要修改时调用 setState 方法。
一个闪烁的文字的例子:
import React, {Component} from 'react';
import {
Text,
StyleSheet,
View
} from 'react-native';
class Blink extends Component {
constructor(props) {
super(props);
this.state = {isShowingText:true};
// 每1000毫秒对showText状态做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { isShowingText: !previousState.isShowingText };
});
}, 1000);
}
render() {
// 根据当前showText的值决定是否显示text内容
if (!this.state.isShowingText) {
return null;
}
return (
<Text>{this.props.text}</Text>
);
}
}
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<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>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems:'center'
},
});
首先,它是自定义了一个 Blink 的组件,在构造函数中初始化了 state,然后写了一个定时器,每个 1 秒改变一次状态,然后 setState,然后在渲染 render()方法中,判断状态的变化,如果是true,显示文字,false 显示空。这样一闪一闪的效果就出来了。
然后我们在BlinkApp中使用Blink组件,并传入我们需要的文字内容即可。
牢记要点:
- 一切界面变化都是状态state变化
- state的修改必须通过setState()方法
- this.state.likes = 100; // 这样的直接赋值修改无效!
- setState 是一个 merge 合并操作,只修改指定属性,不影响其他属性
- setState 是异步操作,修改不会马上生效
Style(样式)
在 React Native 中,你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 CSS 的命名,只是按照 JS 的语法要求使用了驼峰命名法,例如将background-color改为backgroundColor。
style属性可以是一个普通的 JavaScript 对象。这是最简单的用法,因而在示例代码中很常见。你还可以传入一个数组——在数组中位置居后的样式对象比居前的优先级更高,这样你可以间接实现样式的继承。
例子:
import React, {Component} from 'react';
import {
Text,
StyleSheet,
View
} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigBlue}>just bigBlue</Text>
<Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>
<Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text>
<Text style={{color:'red' , fontSize:30}}>
duoduo
<Text style={{color:'blue'}}>
11011
</Text>
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems:'center'
},
bigBlue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
效果图: