React-Native基础(2):聊聊Props和State

原创
2017/05/18 15:05
阅读数 141

React-Native 基于状态实现对DOM控制和渲染。组件状态分为两种:一种是组件间的状态传递、另一种是组件的内部状态,这两种状态使用props和state表示。props用于从父组件到子组件的数据传递。组件内部也有自己的状态:state,这些状态只能在组件内部修改。

Props

在React-Native中大多数组件创建时可以带有不同的参数,这些参数被称为props。 如:React-Native的常用组件Image。当创建Image时,可以用source属性来指定要显示的图片资源。

import React , { Component } from 'react'
import { AppRegistry , Image , } from 'react-native'

class Bananas extends Component {
    render (){
        let pic = {
            uri : 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
        }
        return (
            <Image source={pic} style={{ width : 193 , height : 110}}/>
        );
    }
}

AppRegistry.registerComponent('Bananas', () => Bananas);

自定义的组件也可以使用Props,根据Props名称引用指定的属性值。如在组件Greetingrender方法中用this.props.name应用组件的name属性值。

import React , { Component } from 'react'
import { AppRegistry , Text , View} from 'react-native'

class Greeting extends Component {
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}

class LotsOfGreetings extends Component {
  render() {
    return (
      <View style={{alignItems: 'center'}}>
        <Greeting name='Rexxar' />
        <Greeting name='Jaina' />
        <Greeting name='Valeera' />
      </View>
    );
  }
}

AppRegistry.registerComponent('LotsOfGreetings', () => LotsOfGreetings);

  • 默认属性

使用static定义组件的默认属性值

import React , { Component } from 'react'
import { AppRegistry , Text , View} from 'react-native'
class Greeting extends Component {
  static defaultProps = {
      name : 'alex' , s
  }
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}
...
  • 约束与检查

使用PropTypesProps值的类型进行约束

import React , { Component , PropTypes , } from 'react'
import { AppRegistry , Text , View , } from 'react-native'
class Greeting extends Component {
  ...
  static propTypes = {
      name : PropTypes.string , 
      age : PropTypes.num , 
      greet : PropTypes.func.isRequired ,
  }
  render() {
    return (
      <Text>Hello {this.props.name}!</Text>
    );
  }
}

如果必须使用指定属性值,通过PropTypes.{type}.isRequired来约束。

  • 扩展语法...

传入对象的属性会被复制到组件内,可以多次使用,可以与其他属性组合使用,后面的属性值覆盖之前的属性。JSX 展开属性

import React , { Component , PropTypes , } from 'react'
import { AppRegistry , Text , View , } from 'react-native'
class Greeting extends Component {
  ...
  render() {
    return (
      <Text>Hello {this.props.name}</Text>
    );
  }
}

...
<Greeting {...this.props} name='alex' />
...
  • Props属性解构

通过解构Props属性,直接引用解构后的属性。

import React , { Component , PropTypes , } from 'react'
import { AppRegistry , Text , View , } from 'react-native'
class Greeting extends Component {
  ...
  render() {
    let {name , ...props} = this.props;
    return (
      <Text>Hello {name}</Text>
    );
  }
}

State

控制组件有两种类型数据:PropsStateProps是由父元素设定的固定属性值,在组件整个生命周期中是不可变,使用State来更新数据,刷新UI。 通常在组件构造方法中初始化State,调用setState()方法更新State数据。 简单的文字闪烁的例子,文字的内容在组件创建时使用Props设置为了固定值,文字的闪烁状态则由State来控制。

import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Blink extends Component {
  constructor(props) {
    super(props);
    this.state = {showText: true};

    // 每秒修改State
    setInterval(() => {
      this.setState({ showText: !this.state.showText });
    }, 1000);
  }

  render() {
    let display = this.state.showText ? this.props.text : ' ';
    return (
      <Text>{display}</Text>
    );
  }
}

class BlinkApp extends Component {
  render() {
    return (
      <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属性值

赋值的形式唯一的地方只能在构造器中执行

class ConcreateCompnent extends Component {
    constructor(props){
        super(props);
        this.State = {...};
    }
}

使用setState()函数修改属性

// 错误
this.state.name = 'lucky';
// 正确
this.state.setState={ {name : 'lucky'} };
  • 异步更新State

为了性能,React会批处理连续多个setState操作。 因为this.propsthis.state可能执行一步更新,所以调用this.propsthis.state时的值并不正确。

// 错误
this.setState({
  counter: this.state.counter + this.props.increment,
});

建议setState接收函数的形式来更新state。因为函数的形式会使用前一个state作为第一个参数,同时更新的props属性作为第二个参数。

// 正确
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
  • 合并更新State

调用setState方法时,React会合并提供的state值。

class ConcreateComponent extends Component {
    constructor(props){
        super(props);
        this.state = {
            posts:[] ,
            comments : [] , 
        }
    }
    
    componentDidMount(){
        fetchPosts().then( response => {
            this.setState({
                posts : response.posts
            });   
        });
        
        fetchComment().then( response => {
            this.setState({
                comments : response.comments
            })
        })
    }
}

  • 数据流向

React中的数据流是单向的,只会从父组件传递到子组件。属性props(properties)是父子组件间进行状态传递的接口,React会向下遍历整个组件树,并重新渲染使用这个属性的组件。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部