[关闭]
@fuxinghua 2018-11-14T08:37:15.000000Z 字数 5606 阅读 767

react native数据交互state、props以及redux

props、state、redux


props

props解读

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>
}

}

props属性校验

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使用方式,常用方式即为第一种

state

state解读

官方解释:我们使用两种数据来控制一个组件: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使用

在使用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从而更新视图,这种方式也可以作为跨组件通信的一种方式。

react native(0.57.4)中使用redux

在使用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

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
}

Reducer

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;

store

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的项目已经构建完成。
备注:第一次写,不足之处请指正。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注