1. JSX 소개
①정의
JSX=JavaScript XML은 React 구성 요소 내에 태그를 작성하기 위한 XML과 유사한 구문입니다. React는 JSX를 사용하지 않고도 계속 작동할 수 있지만 JSX를 사용하면 구성 요소의 가독성이 향상되고 JS 의미 체계가 향상되며 구조가 명확해지고 추상화 수준이 높아지며 코드 모듈화가 가능해집니다. 따라서 React에서는 JSX를 사용하는 것이 좋습니다.
②특징
1. 요소 이름의 첫 글자를 대문자로 입력하세요
2. 중첩 규칙을 준수하세요
3. 평가식을 작성할 수 있습니다
4. 카멜케이스 네이밍
5. for, class 등 JavaScript 기본 함수의 일부 키워드는 사용할 수 없습니다. htmlFor 및 className
으로 바꿔야 합니다.③사용방법
1. 동적 값 사용: JSX는 두 개의 중괄호 {...} 사이의 내용을 동적 값으로 렌더링합니다. 중괄호는 자바스크립트 컨텍스트를 지정합니다. 예:
var name=“winty”; <p>{name}</p> function date(d){ return [ d.getFullYear(), d.getMonth()+1, d.getDate() ].join('-); }; <p>{date(new Date()}</p>
2. 댓글: 먼저 하위 노드의 댓글을 중괄호로 묶어야 하며, 한 줄에 /**/ 주석을 달거나 // 여러 줄에 주석을 달 수 있습니다.
var Hello=React.createClass({ render:function(){ return <p name="winty"> //set name Hello ,World /* 多行注释 多行注释 */ </p> } });
3. CSS 인라인 스타일 사용
var style={ color:#000; }; React.render(<div style={style}>....</div>,document.body);
4. 조건부 판단을 활용하세요
//方法1,三目运算符 var Hello=React.createClass({ render:function(){ return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p> } }); //方法2,if-else语句 var Hello1=React.createClass({ getName:function(){ if(this.props.name) return this.props.name; else return "LuckyWinty"; render:function(){ return <p>Hello,{this.getName}</p> } }); //方法3,使用逻辑||运算符 var Hello3=React.createClass({ render:function(){ return <p>Hello,{this.props.name||"LuckyWinty"}</p> } });
④DOM이 아닌 속성 소개
JSX에는 3가지 비DOM 속성, 즉angerlySetInnerHTML, ref 및 key가 있습니다.
dangerouslySetInnerHTML: HTML 코드를 JSX에 직접 삽입하지만, 이 속성을 사용하지 않을 수 있다면 사용하지 않는 것이 좋습니다.
innerHTML을 부적절하게 사용하면 XSS(교차 사이트 스크립팅) 공격이 발생할 수 있습니다. 표시를 위해 사용자 입력을 정리할 때 오류가 자주 발생합니다. 부적절한 정리도 웹 페이지 공격의 원인 중 하나입니다.
보안 결과를 철저히 이해하고 데이터를 적절하게 위생 처리한 후 고유 키 __html만 포함하는 객체가 생성되고, 객체의 값은 위생된 데이터입니다. 예:
function createMarkup() { return {__html: 'First · Second'}; }; <div dangerouslySetInnerHTML={createMarkup()} />
ref: 상위 구성 요소는 하위 구성 요소를 참조하며 속성에 원하는 참조 이름을 설정하여 참조를 정의할 수 있습니다. 예:
... render:function(){ return <div> <input ref="MyInput" .../> </div> } ... //然后你就可以在组件中的任何地方使用this.refs.myInput获取这个引用了
key: 구성 요소에 고유한 키를 설정하고 구성 요소가 렌더링 주기 전반에 걸쳐 일관성을 유지하도록 보장하여 구성 요소를 재사용해야 하는지 또는 파괴하고 다시 빌드해야 하는지 React가 더 쉽게 결정할 수 있도록 하는 선택적 고유 식별자입니다. 렌더링 성능 향상. 예:
var Hello3=React.createClass({ render:function(){ return <ul> <li key="1">1</li> <li key="2">2</li> <li key="3">3</li> </ul> } });
2. React 컴포넌트 수명주기에 대한 자세한 설명
구성 요소는 본질적으로 입력이 결정되고 출력이 결정됩니다. 상태와 결과가 일대일로 대응되므로 프로그램이 직관적입니다. 상태 전환이 발생하면 다양한 후크 기능이 트리거되어 개발자가 응답할 수 있는 기회를 제공합니다. 상태는 사건의 관점에서 이해될 수 있지만 사건은 서로 독립적이지만, 서로 다른 상태는 서로 영향을 미칠 수 있습니다.
구성 요소의 모든 상태가 결합되어 구성 요소의 수명 주기를 형성합니다. 즉, 초기화 단계 -> 실행 단계 -> 파괴 단계입니다.
다양한 수명주기에 따른 맞춤형 기능
초기화 단계:
①getDefaultProps: createClass 이후에 한 번만 호출되는 기본 속성을 가져옵니다. 인스턴스 간 참조 공유
②getInitialState: 각 인스턴스의 고유한 초기화 상태를 초기화합니다
③comComponentWillMount:mout은 로딩을 의미합니다. 이 메소드는 컴포넌트가 페이지에 로드되려는 것을 의미하며 렌더링 전 상태를 수정할 수 있는 마지막 기회이기도 합니다
④render: 컴포넌트는 render 함수에서 가상 노드를 생성하고 최종적으로 React는 가상 노드를 실제 노드로 변환하여 페이지에 렌더링합니다. this.props 및 this.state에만 액세스할 수 있으며 최상위 구성 요소는 하나만 있으므로 상태 및 DOM 출력을 수정하지 않는 것이 가장 좋습니다.
⑤comComponentDidMount: 컴포넌트는 로드될 때까지 호출되지 않습니다. 즉, 이 메소드가 호출되면 컴포넌트가 페이지에 렌더링됩니다.
이 5가지 함수의 실행 순서는 위에서 아래로 입니다. getDefaultProps는 구성 요소의 첫 번째 인스턴스가 초기화될 때만 호출됩니다. 즉, 두 번째 인스턴스는 getInitialState에서 호출됩니다. 기본 속성은 동일한 구성 요소의 모든 인스턴스에 대해 동일합니다.
주요 테스트 코드:
<script type="text/babel"> var Hello=React.createClass({ getDefaultProps:function(){ console.log("getDefaultProps, 1"); }, getInitialState:function(){ console.log("getInitialState, 2"); return null; }, componentWillMount:function(){ console.log("componentWillMount, 3"); }, render:function(){ console.log("render, 4"); return <p>Hi,LuckyWinty!</p> }, componentDidMount:function(){ console.log("componentDidMount, 5"); }, }); React.render(<Hello></Hello>,document.body); </script>
运行结果:
运行中阶段:
①componentWillReceiveProps:这个函数在组件即将接收到属性时触发的,或者是父组件的属性发生变化时,属性在传送到组件之前,开发者有机会通过这个函数去处理属性。比如修改,更新内部状态等。
②shouldComponentUpdate:当组件接收到新属性或者新状态的时候触发的。这个是一个疑问函数,也就是说我们可以告诉react不去更新某个组件。因为有时候属性或者状态并不会导致组件发生更新。在组件不需要更新的情况下,手动使shouldComponentUpdate返回false,这样react就不需要再经过render和diff算法去判断是否要更新,从而提高性能。
③componentWillUpdate:render触发之前触发,更新组件,不能修改属性和状态
④render:组件在render函数生成虚拟节点,最后由react将虚拟节点变成真正的节点渲染到页面上,只能访问this.props和this.state,只有一个顶层组件,最好不要修改状态和DOM输出。
⑤componentDidUpdate:render之后,真正的DOM被渲染之后调用
备注:这五个函数的执行顺序也是从上到下的。这个的测试代码已上传至:https://github.com/LuckyWinty/ReactStudyDemo,欢迎参考!
销毁阶段:
①componentWillUnmount:这个函数在销毁操作真正执行之前调用,给开发者最后的机会进行一些清理工作。
三、属性、状态的含义和用法
属性的含义:
props=properties,属性是不可以由组件自己进行修改的,组件的属性是由父组件传递进来的。
属性的用法:
一)、键值对
<Hello name="winty"/> 字符串 <Hello name={123}/> 大括号包裹的求值表达式 <Hello name={[1,2,3]}/> 传入数组 <Hello name={winty}/> 变量
二)、展开定义(个人认为就是对象式定义)
var props={ one:"123", two:"22" }
这样定义的话,理论上使用应该是one={props.one}这样调用,但是这样写起来比较繁琐,而且如果数据被修改,就需要对应修改相应的赋值,并且无法动态地设置属性,所以react中添加了一种展开语法:
这样使用展开语法,react就会自动把对象中的变量和值当作是属性的赋值,所以Hello实际上就拿到了one、two两个属性,如果没有三个点的话,Hello拿到的实际上就是props对象,使用的时候还需要自己从中取出变量和值
三)、调用react提供的setProps()函数(几乎不用)
var instance=React.render(<HelloWorld></HelloWorld>,document.body); instance.setProps({name:"winty"});
状态的含义:
state,状态是由事物自行处理、不断变化的
状态的用法:
getInitialState:初始化实例的状态
setState:更新组件状态,一旦更新了状态,那么就会触发diff算法,检查内容是否发生变化,若有变化则更新组件,否则就不用。
属性和状态对比
相似点:都是纯JS对象、都会触发render更新、都具有确定性。
属性和状态区分:组件在运行时需要修改的数据就是状态
四、React中事件的用法
事件处理函数:React绑定事件处理器的方法和HTML语法非常类似,所有的事件在命名上与原生的javascript规范一致,并且会在相同的情境下触发。
编写函数
handleClick:function(){
...
}
绑定
onClick={this.handleClick}
各类事件详细说明:
①移动设备上的触摸事件:onTouchCancel、onTouchEnd、onTouchMove、onTouchStart
②键盘类事件:onKeyDown、onKeyPress、onKeyUp
③剪切类事件:onCopy、onCut、onPaste
④表单类:onChange//内容变化即触发、onInput//输入框、onSubmit//禁止表单默认跳转行为
⑤事件:onFocus、onBlur
⑥UI元素类:onScroll
⑦鼠标滚动事件:onWheel
⑧鼠标类型:onClick、onContextMenu//右键菜单、onDoubleClick //双击、onMouseDown、onMouseEnter、onMouseLeave、onMouseMove、onMouseOut、onMouseOver、onMouseUp
⑨拖拽事件:onDrop、onDrag、onDragEnd、onDragEnter、onDragExit、onDragLeave、onDragOver、onDragStart
事件对象介绍
使用方法:就是在编写事件对象处理函数的时候,添加一个参数。拿到这个对象之后,就通过对象的属性来可以获取一些信息。
例如:
handleChange:function(event){ console.log(event.target.value); }
示例中,event就是事件对象,event.target就是事件对象的属性,就是对应的DOM元素,拿到这个元素之后再获取它的值。
事件对象属性
通用属性:
其他不同类型的事件有不同的属性,简单了解一下
知道了事件的一些属性,我们就可以很方便地在React中获取这些属性,进行一些逻辑的处理,实现一些复杂的业务功能、页面效果等。
例如:我们可以利用鼠标事件属性,实时显示鼠标在某个区域的坐标:
<script type="text/jsx"> var HelloWorld = React.createClass({ getInitialState: function () { return { x: 0, y: 0 } }, handleMouseMove: function (event) { this.setState({ x: event.clientX, y: event.clientY }); }, render: function () { return <div onMouseMove={this.handleMouseMove} style={{ height: '500px', width: '500px', backgroundColor: 'gray' }}> {this.state.x + ', ' + this.state.y} </div>; }, }); React.render(<HelloWorld></HelloWorld>, document.body); </script>
x组件协同使用的定义:组件的协同本质上就是对组件的一种组织、管理方式。
组件协同使用的目的:逻辑清晰、代码模块化、封装细节、代码可复用。
组件协同使用的方式:
①组件嵌套使用:也就是说,用一个父组件把子组件包裹起来,本质就是父子关系。如下图描述:
实例代码:
var React = require('react'); var CommentList=require('./CommentList.jsx'); var CommentForm=require('./commentFrom.jsx'); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList /> //这是一个组件 <CommentForm /> //这是另一个组件 </div> ); } }); module.exports = CommentBox;
父子组件之间的通信:
父组件->子组件:通过属性,父组件把数据通过属性来传递给子组件
子组件->父组件:本质上,子组件不能向父组件通信。但是可以间接地通过触发事件来通信,也就是委托。
嵌套组合缺点:
父子关系的具体实现需要经过深思熟虑,贸然编写将导致关系混乱、代码难以维护
无法掌握所有细节,使用者只知道组件用法,不知道实现细节,遇到问题难以修复
②Mixin:也就是可以把相同的代码抽象出来,封装成一个函数,然后再调用。
Mixin的目的:横向抽离出组件的相似代码
相似概念:面向切向面编程、插件
实例代码:
var Time=React.createClass({ mixins:[IntervalMixin(1000)], getInitialState:function(){ return {secondElapsed:0}; }, onTick:function(){ this.setState({secondElapsed:this.state.secondElapsed+1}); }, render:function(){ return ( <div>Seconds Elapsed:{this.state.secondsElapsed}</div> ); } });
mixin相当简单,它们就是混合进组件类中的对象而已。React在这方面实现得更加深入,它能防止静默函数覆盖,同时还支持多个mixin混合。但是这些功能在别的系统中可能引起冲突。例如:
React.createClass({ mixins:[{ getInitialState:function(){ return {a:1}} }], getInitialState:function(){ return {b:2}} });
这样在mixin和组件类中同时定义了getInitialState方法,得到的初始state是{a:1,b:2}.如果mixin中的方法和组件类中的方法返回的对象中存在重复的键,React会抛出一个错误来警示这个问题。
六、React中的双向绑定
React创立的理念跟angular那些框架就是不同的,React是单向数据绑定的。那么怎么实现像angular那样的双向绑定效果呢?看代码:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>React中的双向数据绑定</title> </head> <body> <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script> <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script> <script type="text/jsx"> var BindingMixin = { handleChange: function(key) { var that = this var newState = {} return function(event) { newState[key] = event.target.value that.setState(newState) } } } var BindingExample = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function() { return { text: '', comment: '', } }, render: function() { return <div> <input type="text" placeholder="请输入内容" valueLink={this.linkState('text')} /> <textarea valueLink={this.linkState('comment')}></textarea> <h3>{this.state.text}</h3> <h3>{this.state.comment}</h3> </div> } }) React.render(<BindingExample></BindingExample>, document.body); </script> </body> </html>
效果图(没有CSS样式,有点不优雅,见谅):
以上就是本文的全部内容,希望对大家的学习有所帮助。