@fuxinghua
2018-11-14T08:37:15.000000Z
字数 5606
阅读 767
props、state、redux
props表示属性,官网解读:大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)。
props用途:
1.父子组件通信
2.值校验
定义父组件parent如下:
export default class Parent extends Component<Props>{
render() {
return <View>
<Text>父组件向子组件传值</Text>
<Child parentData={'come from parent data'}/>
</View>
}
}
定义子组件如下:
export default class Child extends Component<Props>{
render() {
return <View>
<Text>{`子组件接受父组件的值:${this.props.parentData}`}</Text>
</View>
}
}
这样就可以通过子组件属性进行通信
当然我们也可以给子组件设置默认props,有属性值的话取到该属性值,没有则取默认属性值,如下
export default class Child extends Component<Props>{
static defaultProps={parentData: 'come from parent default'}
render() {
return <View>
<Text>{`子组件接受父组件的值:${this.props.parentData}`}</Text>
</View>
}
}
1.下载依赖 npm i prop-types --save (yarn add prop-types --save)
2.可以在子组件中属性值进行类型校验,如下:
export default class Child extends Component<Props>{
static defaultProps={parentData: 'come from parent default'}
static propTypes = {
name: PropTypes.string,
age: PropTypes.number
}
render() {
return <View>
<Text>{`子组件接受父组件的值:${this.props.parentData}`}</Text>
<Text>{`子组件接受父组件的姓名值:${this.props.name}`}</Text>
<Text>{`子组件接受父组件的年纪值:${this.props.age}`}</Text>
</View>
}
}
以上即为props使用方式,常用方式即为第一种
官方解释:我们使用两种数据来控制一个组件:props和state。props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state。
一般来说,你需要在 constructor 中初始化state(译注:这是 ES6 的写法,早期的很多 ES5 的例子使用的是 getInitialState 方法来初始化 state,这一做法会逐渐被淘汰),然后在需要修改时调用setState方法。
个人认为:每一个state对应一个view,它存在view的整个生命周期,通过state状态改变,更新view UI布局。为了实现交互,就需要用到组件的state。我们将组件看为状态机,UI是各种各样的状态,并在各种各样的状态之间可以切换,只需要改变组件的state,就会重新渲染UI。
state是组件私有的,是没有办法通过其他组件传递过来的。
官方例子:制作一段不停闪烁的文字。文字内容本身在组件创建时就已经指定好了,所以文字内容应该是一个prop。而文字的显示或隐藏的状态(快速的显隐切换就产生了闪烁的效果)则是随着时间变化的,因此这一状态应该写到state中。
import React, { Component } from 'react';
import { Text, View } from 'react-native';
class Blink extends Component {
constructor(props) {
super(props);
this.state = { showText: true };
// 每1000毫秒对showText状态做一次取反操作
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
}
render() {
// 根据当前showText的值决定是否显示text内容
let display = this.state.showText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
在使用state之前需要在constructor()中初始化state,更改state需通过setState()方式修改,通过this.state.xx修改值无效(0.57.4)如下:
export default class StateComponent extends Component {
// constructor(props) {
// super(props);
// this.state = {
// arr: [1, 2, 3],
// name: 'xiaoli'
// }
// }
// state两种定义方式
state = {
arr: [1, 2, 3],
name: 'xiaoli'
}
render() {
return <View style={{marginTop: 50, backgroundColor: 'green', width: width, justifyContent: 'center', alignItems: 'center'}}>
<Text>{`Name is: ${this.state.name}`}</Text>
<View>
{this._listItem()}
</View>
</View>
}
_listItem() {
return this.state.arr.map((item, index) => {
return <Text key={index} onPress={() => {
this._itemClick(index);
}}>{item}</Text>
})
}
_itemClick(index) {
this.state.arr[index] = this.state.arr[index] + 10;
let demo = this.state.arr;
demo[index] = demo[index] + 10;
this.setState({arr: demo})
}
}
我们都知道每一个state对应一个view,即每一个view维持一个state,当然也可以通过redux管理整个项目数据流,通过dispatch方式修改state从而更新视图,这种方式也可以作为跨组件通信的一种方式。
在使用redux之前需要安装必要对依赖,该讲解只是redux一个简单应用,只需安装:
npm i redux --save 或者 (yarn add redux --save)
npm i react-redux --save 或者 (yarn add react-redux --save)
redux和react、react native没有关联。redux只是作为一个数据管理者,管理着众多state(状态)。当然这里只是简单描述,
核心概念点击---核心概念
三大原则点击---三大原则
先前技术点击---先前技术
备注:以上3条来自redux官网,详情点击
下面介绍redux几个主要模块
Action是把数据从应用传到store的有效载荷,是store数据的唯一来源,一般通过store.dispatch()将action传到store。比如可以定义action如下:
import * as CountTypes from '../constants/countTypes'
const decAction = function () {
return {
type: CountTypes.DECREMENT
}
}
const addAction = function () {
return {
type: CountTypes.INCREMENT
}
}
const resetAction = function () {
return {
type: CountTypes.RESET
}
}
export {
addAction,
decAction,
resetAction
}
Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。在 Redux 应用中,所有的 state 都被保存在一个单一对象中,所以我们可以在reducer中对state进行逻辑处理,可以定义reducer如下:
import * as countTypes from '../constants/countTypes'
const initState = {
count: 8,
factor: 1
}
export default function count(state = initState, action) {
switch (action.type) {
case countTypes.RESET:
return {
...state,
count: 0
}
case countTypes.INCREMENT:
return {
...state,
count: state.count + state.factor
}
case countTypes.DECREMENT:
return {
...state,
count: state.count - state.factor
}
default:
return state
}
}
多个或者单个action需要处理,就需要扩展reduce,通过combineReducers连接,代码如下:
import {combineReducers} from 'redux';
import count from './countReduce'
const reducers = combineReducers({
count
})
export default reducers;
Redux 应用只有一个单一的 store,当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。
Store 就是把它们联系到一起的对象。Store 有以下职责:
维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
代码如下:
import {createStore} from 'redux';
import reducers from '../reducers/index'
function configureStore(initialState) {
return createStore(
reducers,
initialState,
);
}
const store = configureStore();
export default store;
Action、reducer、stroe定义好以后就可以使用redux管理我们构建的react native项目。
具体实现如下:
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Button} from 'react-native';
import {connect} from 'react-redux';
import * as countAction from '../../actions/countAction'
type Props = {};
class Count extends Component<Props> {
render() {
return <View>
<Text>Redux管理数据流</Text>
<Text>-------------------</Text>
<Text>{`计算值:${this.props.store.getState().count.count}`}</Text>
<View style={{flexDirection: 'row',}}>
<Button color="red" title='加+' onPress={() => {
this.props.store.dispatch(countAction.addAction())
}}/>
<Button color='green' title='减-' onPress={() => {
this.props.store.dispatch(countAction.decAction())
}}/>
<Button color='#841584' title='重置' onPress={() => {
this.props.store.dispatch(countAction.resetAction())
}}/>
</View>
</View>
}
}
function select(store) {
return {
count: store.count.count,
}
}
export default connect(select)(Count)
至此一个简单的redux结合react native的项目已经构建完成。
备注:第一次写,不足之处请指正。