ReactJS入门(一)—— 初步认识React

web开发作者:dayu日期:5天前点击:0

于是好处显而易见,并非每修改一次组件的state,就会重新渲染一次,而是在Event loop结束后做一次“秋后算账”,减少冗余的DOM操作。另外React只针对需要修改的地方来做新的渲染,而非重新渲染整个DOM树,自然效率很是不错。

2. 组件可嵌套,而且,可以模版化嘛 —— 其实在React里提及的“组件”,常规是一些可封装起来、复用的UI模块,说的接地气了可以理解为“带有细粒度UI功能的部分DOM区域”。然后我们可以把这些组件层层嵌套起来使用(当然这样组件间会存在依赖关系)。

至于模块化,类似于ejs那样可以作为独立的模块被引用到页面上来复用,不过咧,它可以直接把UI组件当作脚本模块那样来使用,咱完全可以配合CommonJS、AMD、CMD等规范来require需要的组件模块,并处理好它们的依赖关系(是不是碉堡了)。

基于上述的俩点,自然的也打算投入React怀抱了。不过在这之前得先理清俩点事情:

1. React是一个纯View层,不擅长于和动态数据打交道(哎哟咱也不谈Flux了,Flux的概念其实也不完善),因此它不同于,也替代不了常规的MV*框架;

2. React很擅长于处理组件化的页面,在页面上搭组件的形式有点像搭乐高一样,因此用上React的项目需求常规为界面组件化。另外React只支持到IE8+,就天朝的情况,是否使用React还是得稍微斟酌一番。

唠嗑了这么多,下面开始进入React的入门课程。本章提及的代码都可以在我的Github上下载到。

技术分享

JSX

JSX是React编写组件的一种语法规范,可以看为是js的扩展,它支持将HTML和JS混写在一起,最终会通过React提供的JSXTransformer.js来将其编译为常规的js,方便浏览器解析。我们来个最简单的例子:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>最简单的jsx</title>
    <script src="react.js"></script>
    <script src="JSXTransformer.js"></script>
</head>
<body>
<div。

然后我们定义了个变量name,并使用了React最基础和最常用的一个方法React.render()来渲染DOM:

 var name = ‘VaJoy‘;
    React.render(<h1>{name}</h1>, document.getElementById(‘a‘));

React.render()支持两个参数(其实还有第三个可选的参数,作为渲染后的回调),第一个参数为模板的渲染内容(HTML形式),第二个参数表示要插入这段模板的DOM节点(DOM node)

这里要提及一个知识点 —— 在JSX中,遇到 HTML 标签(以 < 开头),将用 HTML 规则解析;遇到代码块(以 { 开头),则用 JavaScript 规则解析。所以我们在<h1>中嵌入变量 name 时是以花括号的形式 {name} 来实现的。

至于执行结果,相信大家很容易猜出来:

技术分享

即往div里插入了(其实应该说是彻底替换为)JSX中的模板内容(<h1>元素)

技术分享

鉴于JSX支持HTML跟JS的混写,故其灵活性很高,我们试着把变量换为数组:

var arr = [‘HELLO‘, "here is", 123, "VaJoy`s blog"];
    React.render(
        <ul>{
            arr.filter(function(v){
                return typeof v === ‘string‘
            }).map(function(v){
                return <li> {v} </li>
            })
        }</ul>,
        document.getElementById(‘a‘)
    );

结果如下:

技术分享

技术分享

组件

开头已经提及React是用于组件化开发的,组件可看为是其最小组成单位,那么什么是组件(component)呢?我们看看下方这张图:

技术分享

这是一个移动端上的UI界面,用于查询员工列表和某员工的具体信息。那么我们按页面上各功能来细分,以左侧的搜索主页界面而言,可以把它细分为SearchBar、EmployeeList、EmployeeListItem等UI组件,其中EmployeeList组件嵌套了多个EmployeeList组件,而这众多组件的搭配组成了整个Hompage界面。

常规我们用React开发的页面可以看为一个大组件,它由多个小组件搭建而成。

在JSX中,我们可以通过React.createClass()方法来创建一个组件(注意组件的名称必须为大写字母开头),并以命名标签的形式(<MyClassName />)来引用:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>组件</title>
    <style>
        .nameStyle{
            color: dodgerblue;
        }
    </style>
    <script src="react.js"></script>
    <script src="JSXTransformer.js"></script>
</head>
<body>
<div>{a,name}</p> //当然你可以写为{a}{name}
            );
        }
    });
    React.render(
        <Demo />,  //引入组件Demo
        document.getElementById(‘a‘)
    );
</script>
</body>
</html>

注意每个组件都需要有一个render方法,用于输出组件内容。另外组件DOM元素上的class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

执行效果如下:

技术分享

可以看到,如果在一个容器中引用了多个变量,React会对应每个文本节点来自动生成对应span标签(React防止XSS的机制,因此要注意规避span的样式污染!)

再来看个组件嵌套的示例,其实都很简单:

技术分享View Code

注意在JSX里,给DOM设置 style 必须写成{{ marginRight : ‘10px‘, fontSize : ‘18px‘ }}的映射形式(预防XSS),否则会报错

执行结果(注意连空格都生成了一个span)

技术分享

技术分享

组件的“数据”

我们在前头提及了,React只是一个纯view层,并不涉及model。不过但对于React组件而言,它有两种特殊的data ——PropsStates。其中的States有点类似于各MV*框架中的model部分,可以称为React的状态机制,用于与用户进行交互。

1. Props

props表示组件自身的属性,也可以用于在嵌套的内外层组件中传递信息(常规是由父层组件传递给子层组件)。要注意它是不变的、也不应该尝试去改变的。我们来个简单的示例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>组件Props</title>
    <script src="react.js"></script>
    <script src="JSXTransformer.js"></script>
</head>
<body>
<divonClick={this.handleClick}>
                        <Component1 abc="你好!" name="张三" />
                        <Component1 abc="Hi!" name="李四" />
                    </div>
            );
        },
        handleClick: function (e) {
            console.log(this.props.name, e.target);
        }
    });
    React.render(
        <Component2 name="我是Component2的name哦!" />,
        document.getElementById(‘a‘)
    );
</script>
</body>
</html>
复制代码

这里我们注册了俩个组件类Component1 和Component2 ,其中Component2 内嵌了Component1 。

我们先看Component1 的定义:

 var Component1 = React.createClass({
        render: function() {
            return <p> {this.props.abc, this.props.name} </p>;
        }
    });

它返回了一个p标签,其中的内容是 this.props.abc 和 this.props.name,这里的 this 指的是组件Component1 本身,因此比如this.props.name 获取到的便是组件Component1 自身的属性 name 的值(abc 和 name 的值我们都在 Component2 中进行了定义)。

我们接着看Component2:

  var Component2 = React.createClass({
        render: function() {
            return (
                    <div className="commentList" onClick={this.handleClick}>
                        <Component1 abc="你好!" name="张三" />
                        <Component1 abc="Hi!" name="李四" />
                    </div>
            );
        },
        handleClick: function (e) {
            console.log(this.props.name, e.target);
        }
    });

在这里我们除了嵌入组件Component1 并定义了它们的属性值 abc 和 name ,也使用了React的事件机制——我们用 onClick 方法来触发点击事件,其对应的 this.handleClick 是我们自定义的一个方法,用于输出Component2 的 name 属性和当前被点击的目标元素。

最后我们用 React.render 方法渲染组件 Component2 ,并定义了它的 name 属性:

 React.render(
        <Component2 name="我是Component2的name哦!" />,
        document.getElementById(‘a‘)
    );

执行结果如下:

技术分享

这里有点要留意的,无论是 props 组件属性,或者是 onClick 事件,都是 React 内部的东西,我们在HTML上是看不到它们的:

技术分享

技术分享

顺便提个Props的语法糖 —— 我们可以通过 “...this.props” 来将父层组件绑定的全部属性都直接写到子组件中:

技术分享View Code

执行结果:

技术分享

技术分享

Props也并非都是直接写在组件标签上的属性,有一个例外 —— props.children,它表示当前组件的所有子节点(它们常规是在外部的组件赋予的)

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>props.children</title>
    <style>
        p:active{ color: deeppink; }
    </style>
    <script src="react.js"></script>
    <script src="JSXTransformer.js"></script>
</head>
<body>
<divsrc="http://image.mamicode.com/info/201707/20180110235820549239.png" >

技术分享

2. State

State 是组件的状态,它是可变的,因此常用于跟用户的交互。

不同于Props,我们需要在组件中使用getInitialState() 方法来初始化组件的State,并使用 this.setState() 来修改State的值:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>state</title>
    <style>
        p:active{ color: deeppink; }
    </style>
    <script src="react.js"></script>
    <script src="JSXTransformer.js"></script>
</head>
<body>
<divonChange={this.clickCb} />{ text }
            </div>;
        },
        clickCb: function(){
            this.setState({
                isClick : !this.state.isClick  //点击checkbox时改变state.isClick
            })
        }
    });

    React.render(
        <Component />,
        document.getElementById(‘a‘)
    );
</script>
</body>
</html>

我们先通过getInitialState() 方法初始化了组件Component的State对象,里面有个 isClick 的属性,默认值为 false。

接着在组件的 render 方法里定义了一个 text 变量,其值会根据 state.isClick 的变化而变化:

var text = this.state.isClick ? ‘clicked!‘ : ‘none click‘;

另外给checkbox控件绑定了React的 onChange 事件,checkbox的勾选状态改变时触发组件的 clickCb 自定义回调事件,它是这样的:

  clickCb: function(){
            this.setState({
                isClick : !this.state.isClick  //点击checkbox时改变state.isClick
            })
        }

如注释,它会通过 this.setState 方法来改变 state.isClick 的值,进而依赖于state.isClick 的变量 text 的值也会间接变化:

技术分享

ReactJS入门(一)—— 初步认识React

原文地址:http://www.cnblogs.com/d-xs/p/7210902.html


下一篇       上一篇