美文网首页
RN(三)--React JSX、初识React组件化

RN(三)--React JSX、初识React组件化

作者: doudo | 来源:发表于2018-01-03 16:59 被阅读213次

    一、React JSX

    1. JSX简介

    JSX就是Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。

    如下(JS写法)

    var child1 = React.createElement('li', null, 'First Text Content');
    var child2 = React.createElement('li', null, 'Second Text Content');
    var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
    

    等价于(JSX写法)

    var root =(
      <ul className="my-list">
        <li>First Text Content</li>
        <li>Second Text Content</li>
      </ul>
    );
    

    后者将XML语法直接加入JS中,通过代码而非模板来高效的定义界面。之后JSX通过翻译器转换为纯JS再由浏览器执行。在实际开发中,JSX在产品打包阶段都已经编译成纯JavaScript,JSX的语法不会带来任何性能影响。另外,由于JSX只是一种语法,因此JavaScript的关键字class, for等也不能出现在XML中,而要如例子中所示,使用className, htmlFor代替,这和原生DOM在JavaScript中的创建也是一致的。JSX只是创建虚拟DOM的一种语法格式而已,除了用JSX,我们也可以用JS代码来创建虚拟DOM.

    2. JSX!=HTML

    JSX形式上非常像常见的HTML,但它并不是一种标记语言,它实,是调用React.createElement函数,所以在使用JSX时,务必在头部
    import React from ‘react’;
    JSX只是借鉴HTML的规则/规范:

    • 开始和结束标签配对
      <组件>....</组件>
    • 无内容的组件标签应写为自封闭形式
      <组件></组件>应写为<组件 />
    • 可自定义属性,字符串值应用双引号,其他值用{}括起来
      <person name="Tom" age={30} married={true} />
    • 布尔值可省略值
      <person married />等价于<person married={true} />
    • 必须单一子节点


    • "空值"自动忽略
      <div />
      <div></div>
      <div>{false}</div>
      <div>{true}</div>
      <div>{null}</div>
      <div>{undefined}</div>
      //所以可以用来显示或隐藏标签
    <View>
    {isShow && <Text>Warning</Text>} //此处若isShow为true,则返回text组件(并非true值),所以可以显示
    </View>
    
    • 组件必须大写字母开头
    • 文本必须写在Text组件内
    <View>
    <Text>
    你好吗!
    </Text>
    </View>
    
    • 注释比较特殊是{/**/},有别于js部分的//和/**/
      {/*<View />*/}
    • 只能嵌入表达式
    //错误写法
    {if(true) {return <Text />}};
    {for(let i=0; i<arr.length; i++) {....}};
    
    //正确的写法
    {isTrue && <Text />};
    {arr.map(i=><Text>{i.text}</Text>)};
    
    //如果是复杂的逻辑可以另写函数在这里只是调用
    {doSomething()};
    

    更多内容,可看Introducint JSX
    facebook.github.io/react/docs/introducing-jsx.html
    JSX In Depth
    https://facebook.github.io/react/docs/jsx-in-depth.html

    三、初识React组件化开发

    首先,介绍一款在线的模拟器
    ),非完整模拟,但是我们可以用来练习基础。

    1. class/function都可以作为积木(组件)
    //class
    class GoodMorning extends Component {
      render() {
        return (
          <Text>GoodMorning</Text>
        )
      }
    }
    //function
    const GoodEvening = () => {
      return
      (
        <Text>GoodEvening</Text>
      )
    }
    
    //都可以作为App的组件
    export default class App extends Component {
    render() {
        return (
          <View>
            <GoodMorning />
            <GoodEvening />
          </View>
        )
      }
    }
    

    输出:

    GoodMorning
    GoodEvening
    
    2. 使用属性props定制“积木”(组件)
    class GoodMorning extends Component {
      render() {
        return (
          <Text>GoodMorning,{this.props.name}</Text>
        )
      }
    }
    
    const GoodEvening = (props) => {
      return
      (
        <Text>GoodEvening,{props.name}</Text>
      )
    }
    
    export default class App extends Component {
    render() {
        return (
          <View>
            <GoodMorning name="Li" /> {/*使用时传入属性*/}
            <GoodMorning name="Wang" /> {/*使用时传入属性*/}
          </View>
        )
      }
    }
    

    输出:

    GoodMorning,Li
    GoodEvening,Wang
    
    3. defaultProps默认值和propTypes类型约束
    class Demo extends Component{
    static defaultProps = {
      name : 'WangDaChui',//赋值默认值
    }
    static propTypes = {
      name : React.propTypes.string,//约定类型为string
    }
    
    render...
    }
    

    defaultProps和propTypes写法类似(都为静态成员属性)。
    propTypes只在开发阶段有效,发布时会被自动移除。
    根据编码习惯爱好自由取舍。

    4. 变量作用域
    • 函数内的局部变量,只能函数内读写,函数运行结束,自动销毁。
    • class内的成员变量,在单个class的实例内读写,实例销毁时,一并销毁。使用时,使用this。
    • class内的静态成员变量,在所有class的实例中共享,不会自动销毁。而且其他模块可以通过此class访问(类public)。
    • class外的变量,在所有class实例内共享,不自动销毁。除非明确export,否则其他模块不可访问(类private)。
    • global全局变量,任何地方都可读写(类浏览器的window),不自动销毁。
      global.test = 1;则以后任何地方都可以alert(global.test)alert(test)
    5. class内的成员变量写法
    class Demo extends Component{
        name = 'Tom'; //注意没有任何let var声明符号
        render(){....}
    }
    

    //我们写的时候还是推荐上边的写法。还有一种写法,是老写法,我们知道即可:

    class Demo extends Component {
        constructor(props) {
            super(props);  // 照抄即可,不可省略
            this.xxx = 1;    //声明的成员变量
        }
        render() {
        …….
        }
    }
    
    
    6. 动态生成组件列表与key
    • 根据多个数据生成多个组件,我们一般使用map方法。注意,箭头函数的返回值,如果有{},记得加return。
    • 循环生成的组件需要有唯一的key值区分,因为有Virtual DOM(Virtual Dom我们后边会介绍)。
    {['a','b'].map(i=><Text key={i}>{i}</Text>)}
    

    1.key属性放在循环的直接容器上。
    2.key值优先使用区分度较高的值(id,具体内容),其次考虑数组下标。
    3.key值只需在当前循环中不重复。

    7. state

    万物生长靠太阳,界面变化靠状态(state)

    • 一切界面变化都是state的变化。
    • state的修改必须通过setState()方法:this.setState({ likes : 3, })
    • setState是异步操作,修改不会马上生效。
      看一段例子就能理解,定义、使用、修改:
    export default class App extends Component {
      state = { //定义state
        likes : 2,
      }
      onPress = ()=>{
        const {likes} = this.state;
        this.setState({ //通过setState,修改state中的值
          likes : likes+1,
        }
        )
      }
    render() {
      return(
          <View>
          <TouchableOpacity onPress={this.onPress}>
            <Text>{this.state.likes}</Text> //使用state中的值
          </TouchableOpacity>
          </View>
      )
      }
    }
    
    8. VIRTUAL DOM

    状态的变化会带来界面的变化,状态不断变化会带来性能问题吗?

    React会自动计算出差异部分,以最小的差异去重新渲染,在内存中“打草稿”的这一概念便称为VIRTUAL DOM。

    VIRTUAL DOM,正式通过key来判断哪些是已有的,哪些是新增的,以最小的差异去重新渲染。

    参考:
    React Native中文网

    相关文章

      网友评论

          本文标题:RN(三)--React JSX、初识React组件化

          本文链接:https://www.haomeiwen.com/subject/hgrqnxtx.html