React重点概要

JSX语法:

1.ReactDOM.render:用于将模板转换为HTML语言,并插入指定的DOM节点;

 语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析,HTML 语言直接写在 JavaScript 语言之中,不加任何引号

1<div id="example"></div> 2 <script type="text/babel"> 3 ReactDOM.render( 4 <h1>Hello, world!</h1>, 5 document.getElementById('example') 6 ); 7 </script>

2. 它允许 HTML 与 JavaScript 的混写

语法规则:遇到代码块(以 { 开头),就用 JavaScript 规则解析

1var names = ['Alice', 'Emily', 'Kate']; 2 3 ReactDOM.render( 4 <div> 5 { 6 names.map(function (name) { 7 return <div>Hello, {name}!</div> 8 }) 9 } 10 </div>, 11 document.getElementById('example') 12 ); 13 14结果为:hello Alice hello Emily hello Kate

3.直接在模板插入 JavaScript 变量,如果这个变量是一个数组,则会展开这个数组的所有成员

1var arr = [ 2 <h1>Hello world!</h1>, 3 <h2>React is awesome</h2>, 4 ]; 5 ReactDOM.render( 6 <div>{arr}</div>, 7 document.getElementById('example') 8 ); 9结果:Hello wold! React is awesome

**二、组件:**React 允许将代码封装成组件(component),然后像插入普通 HTML 标签一样,在网页中插入这个组件

1.React.createClass用于生成一个组件类,所有组件类都必须有自己的 render 方法,用于输出组件

语法规则:

       1)组件类的第一个字母必须大写,否则会报错:如HelloMessage写成helloMessage就会报错(例1)  

      2)组件类只能包含一个顶层标签(例2)

例1:

1var HelloMessage = React.createClass({ 2 render: function() { 3 return <h1>Hello {this.props.name}</h1>; 4 } 5 }); 6 7 ReactDOM.render( 8 <HelloMessage name="John" />, 9 document.getElementById('example') 10 ); 11 

变量 HelloMessage 就是一个组件类,<HelloMessage /> 会自动生成 HelloMessage 的一个实例 

例2:   

1var HelloMessage = React.createClass({ 2 render: function() { 3 return <h1> 4 Hello {this.props.name} 5 </h1><p> 6 some text 7 </p>; 8 } 9 });

 这种写法就会报错:因为有两个顶层标签h1和p

3.给组件添加自定义属性:

语法规则:

  1)为组件HelloMessage添加一个name属性

  2)在组件类中使用this.props对象获取属性值

  3)因为class和for是js的保留字,所以  clss需要写成:className,for需要写成:htmlFor

1var HelloMessage = React.createClass({ 2 render: function() { 3 return <h1>Hello {this.props.name}</h1>; 4 } 5 }); 6 7 ReactDOM.render( 8 <HelloMessage name="John" />, 9 document.getElementById('example') 10 );

**三、this.props.children属性:**表示组件的所有子节点

1var NotesList = React.createClass({ 2 render: function() { 3 return ( 4 <ol> 5 { 6 React.Children.map(this.props.children, function (child) { 7 return <li>{child}</li>; 8 }) 9 } 10 </ol> 11 ); 12 } 13 }); 14 15 ReactDOM.render( 16 <NotesList> 17 <span>hello</span> 18 <span>world</span> 19 </NotesList>, 20 document.body 21 );结果:1.hello 2.world

以上为: 通过this.props.children来读取NodeList组件的两个子节点span

注意1:this.props.children有三种可能值:

  1)没有子节点时:undefined

  2) 一个子节点时:Object

  3) 多个子节点时:Array

注意2:可以使用React.Children.map来遍历子节点(更多方法官方文档

**四、PropTypes属性:**就是用来验证组件实例的属性是否符合要求

注:组件的属性可以接受任意值,字符串、对象、函数等等都可以

1var MyTitle = React.createClass({ 2 propTypes: { 3 title: React.PropTypes.string.isRequired, 4 }, 5 6 render: function() { 7 return <h1> {this.props.title} </h1>; 8 } 9 });

 PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。现在,我们设置 title 属性的值是一个数值就会报错。更多的PropTypes设置看官网

五、getDefaultProps方法:可以用来设置组件属性的默认方法

1var MyTitle = React.createClass({ 2 getDefaultProps : function () { 3 return { 4 title : 'Hello World' 5 }; 6 }, 7 8 render: function() { 9 return <h1> {this.props.title} </h1>; 10 } 11}); 12 13ReactDOM.render( 14 <MyTitle />, 15 document.body 16);结果:Hello World

六、获取真实的DOM节点:

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。

但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性。

1var MyComponent = React.createClass({ 2 handleClick: function() { 3 this.refs.myTextInput.focus(); 4 }, 5 render: function() { 6 return ( 7 <div> 8 <input type="text" ref="myTextInput" /> 9 <input type="button" value="Focus the text input" onClick={this.handleClick} /> 10 </div> 11 ); 12 } 13 }); 14 15 ReactDOM.render( 16 <MyComponent />, 17 document.getElementById('example') 18 );

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。

需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。

React 组件支持很多事件,除了 Click 事件以外,还有 KeyDownCopyScroll

**七、this.state:**将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI

1var LikeButton = React.createClass({ 2 getInitialState: function() { 3 return {liked: false}; 4 }, 5 handleClick: function(event) { 6 this.setState({liked: !this.state.liked}); 7 }, 8 render: function() { 9 var text = this.state.liked ? 'like' : 'haven\'t liked'; 10 return ( 11 <p onClick={this.handleClick}> 12 You {text} this. Click to toggle. 13 </p> 14 ); 15 } 16 }); 17 18 ReactDOM.render( 19 <LikeButton />, 20 document.getElementById('example') 21 );

getInitialState:方法用于定义初始状态,也就是一个对象。

this.state:读取getInitialState返回的状态值  如:liked:false。

this.setState:修改状态值,每次修改以后自动调用this.render方法,在此渲染组件。

this.pros和this.setState的区别:

   1)this.props:用于一旦定义就不再改变的特性;

   2)this.setState:随着用户互动而产生变化的特性

**九、表单:**用户再表单输入的内容,属于用户跟组件互动,所以不能用this.props读取

1var Input = React.createClass({ 2 getInitialState: function() { 3 return {value: 'Hello!'}; 4 }, 5 handleChange: function(event) { 6 this.setState({value: event.target.value}); 7 }, 8 render: function () { 9 var value = this.state.value; 10 return ( 11 <div> 12 <input type="text" value={value} onChange={this.handleChange} /> 13 <p>{value}</p> 14 </div> 15 ); 16 } 17 }); 18 19 ReactDOM.render(<Input/>, document.body);

 onChange:事件的回调函数

event.target.value:读取用户输入的值

注:像textarea、select、redio都属于这种情况

十:组件的声明周期:

1.组件的生命周期分为三个状态:

  Mounting:以插入真实DOM

  Updating:正在被重新渲染

  Unmounting:已移除真实DOM

2.React为每个状态都提供了两种处理函数:

  wil:函数正在进入状态之前调用

  did:函数在进入状态之后调用

3.三种状态共计五种处理函数:

  componentWillMount()

  componentDidMount()

  componentWillUpdate(object nextProps,object nextState)

  componentDidUpdate(object prevProps,object prevState)

  componentWillUnmount()

4.特殊状态:

  componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用

  shouldComponentUpdate(object nectProps,object nextState):组件判断是否重新渲染时调用

1var Hello = React.createClass({ 2 getInitialState: function () { 3 return { 4 opacity: 1.0 5 }; 6 }, 7 8 componentDidMount: function () { 9 this.timer = setInterval(function () { 10 var opacity = this.state.opacity; 11 opacity -= .05; 12 if (opacity < 0.1) { 13 opacity = 1.0; 14 } 15 this.setState({ 16 opacity: opacity 17 }); 18 }.bind(this), 100); 19 }, 20 21 render: function () { 22 return ( 23 <div style={{opacity: this.state.opacity}}> 24 Hello {this.props.name} 25 </div> 26 ); 27 } 28}); 29 30ReactDOM.render( 31 <Hello name="world"/>, 32 document.body 33);

 注意:1)style的格式:style={{opacity: this.state.opacity}}

  1. 注意setinterval()方法中,回调函数一定要加.bind(this)方法,原因是:在setInterval()中定义的回调函数,是在同步代码执行完后,随着事件触发来异步执行的,此时函数的上下文Context已经由定义该函数的Script文件变为全局变量,如果不通过bind(this)来指定由组件实例作为上下文的话,回调函数中的this会指向全局变量中的Window变量,显然不是我们想要的结果。

十一、Ajax

组件的数据来源,通常是通过 Ajax 请求从服务器获取,可以使用 componentDidMount 方法设置 Ajax 请求,等到请求成功,再用 this.setState 方法重新渲染 UI

1var UserGist = React.createClass({ 2 getInitialState: function() { 3 return { 4 username: '', 5 lastGistUrl: '' 6 }; 7 }, 8 9 componentDidMount: function() { 10 $.get(this.props.source, function(result) { 11 var lastGist = result[0]; 12 if (this.isMounted()) { 13 this.setState({ 14 username: lastGist.owner.login, 15 lastGistUrl: lastGist.html_url 16 }); 17 } 18 }.bind(this)); 19 }, 20 21 render: function() { 22 return ( 23 <div> 24 {this.state.username}'s last gist is 25 <a href={this.state.lastGistUrl}>here</a>. 26 </div> 27 ); 28 } 29 }); 30 31 ReactDOM.render( 32 <UserGist source="https://api.github.com/users/octocat/gists" />, 33 document.body 34 );

 我们甚至可以把一个Promise对象传入组件

1var RepoList = React.createClass({ 2 getInitialState: function() { 3 return { loading: true, error: null, data: null}; 4 }, 5 6 componentDidMount() { 7 this.props.promise.then( 8 value => this.setState({loading: false, data: value}), 9 error => this.setState({loading: false, error: error})); 10 }, 11 12 render: function() { 13 if (this.state.loading) { 14 return <span>Loading...</span>; 15 } 16 else if (this.state.error !== null) { 17 return <span>Error: {this.state.error.message}</span>; 18 } 19 else { 20 var repos = this.state.data.items; 21 var repoList = repos.map(function (repo) { 22 return ( 23 <li> 24 <a href={repo.html_url}>{repo.name}</a> ({repo.stargazers_count} stars) <br/> {repo.description} 25 </li> 26 ); 27 }); 28 return ( 29 <main> 30 <h1>Most Popular JavaScript Projects in Github</h1> 31 <ol>{repoList}</ol> 32 </main> 33 ); 34 } 35 } 36 }); 37 38 39ReactDOM.render( 40 <RepoList 41 promise={$.getJSON('https://api.github.com/search/repositories?q=javascript&sort=stars')} 42 />, 43 document.body 44);

 如果Promise对象正在抓取数据(pending状态),组件显示"正在加载";如果Promise对象报错(rejected状态),组件显示报错信息;如果Promise对象抓取数据成功(fulfilled状态),组件显示获取的数据

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )