网页总是一个链接着另一个的,React一大优势在于每次链接到另一个页面上去的时候,不需要向传统页面一样,得销毁所有代码,重新渲染新页面的代码,而只在一个页面上展现新的内容——单页页面。React另一个优势是,以往的单页页面你需要考虑哪个元素要被删除、哪个元素的行为要被修改,而我们只需要告诉React我们想要的最终页面的效果,React会自动帮我们处理页面上的元素,做删除、修改等操作。而我只知道React有自己的虚拟DOM,它会对比虚拟DOM和真实DOM的差别,然后在适当的时机更新页面。至于它怎么对比的?怎么知道差别的?怎么进行修改的?我不知道,不过,对于我们,谁在乎呢?必须首先知道的关于React的术语JSX语法:React特有语法,用来搭建虚拟DOM组件(Component):一个个代码块,用来封装各种功能,可以类比于函数(function)props&status:组件的所有静态属性 & 所有动态属性引入React想要使用React,你需要先引入:<script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script><script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin</script><script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script>上面两个<script>引入了React的核心库,最后一句<script>引入jsx语法编译器,因为浏览器不懂jsx只知道javascript,所以,引入编译器转换为浏览器能懂的javascript语言请参考React官方文档以获取最新版本React的引入:https://reactjs.org/docs/add-…初步使用React并没有什么特别的技巧,先看代码,再做解释:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); ReactDOM.render( <div> <p>Batman</p> <p>catwoman</p> </div>, container ); </script></body></html>解释:首先引入了三个<script>新建一个元素<div id=“container”></div>我们必须在一个<scripr type=“text/babel”>中使用React,请注意<script>的type像一般的javascript语法一样,我们先获取页面元素var container = document.querySelector("#container”);修改虚拟DOM,并渲染真实DOM其中,ReactDOM.render();就是在渲染,其含义是将第一个参数渲染到第二个参数下。而第一个参数<div>…</div>就是新的虚拟DOM的内容,可更改为我们想要的真实DOM结构。ReactDOM.render( <div> <p>Batman</p> <p>catwoman</p> </div>, container);效果、页面结构我们看到,页面中已经添加了包含两个<p>元素的<div>。React.render()函数的第一个参数只能是一个标签,不能是并列的两个标签。不过一个标签里的子标签可以随便的添加,所以最好的方法就是,在外面添加一个<div></div>使用组件(Component)上面的方法是直接将你想要的写在React.render()里,通常的做法是引用组件定义一个组件class 组件名 extends React.Component( //your code);组件里可以添加很多功能,比如想要添加一个按钮,你只需直接写你想要的DOM结构,而不需要使用javascript语法:createElement()、appendChild()等class 组件名 extends React.Component( render(){ return (<button>Batman</button>); });在组件里写好你想要的东西,使用React.render()进行渲染React.render( <组件名/>, 想要渲染的位置)完整代码可以如下<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Myname extends React.Component{ render(){ return (<button>Batman</button>); } }; ReactDOM.render( <Myname/>, container ); </script></body></html>效果、页面结构我们看到,页面上出现了我们想要的按钮,页面结构里也成功添加了<button>标签。注意!!!组件名首字母必须大写!!!引用组件注意代码<组件名/>,一个符号都不能错的!!!使用propsprops用来获取组件的静态属性,可以先看下面的一个小例子:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Myname extends React.Component{ render(){ return (<button type={this.props.buttontype}>{this.props.children}</button>); } }; ReactDOM.render( <Myname buttontype=“submit”>Batman</Myname> , container ); </script></body></html>不必惊慌,修改的地方只有组件的render()和实际渲染的render()两个函数。第一个render()添加了<button>的type属性,该属性值指向{this.props.buttontype},意思是该组件名为buttontype的静态属性。这个render()还将<button>的显示文字指向{this.props.children},意思是该组件的子元素这个静态属性第二个render()函数添加了<Myname>的静态属性buttontype,和一个text类型的子元素Batman结论就是:在渲染真实DOM的时候,会创建一个<button></button>标签,它的type属性值为submit,文字显示为Batman效果、页面结构,哈哈哈,没啥区别,没区别就对了:props的传递性props只能从父元素向下传递给子元素:当有多个属性你想传递的时候,你的代码可能就会是这样的,会重复很多遍{this.props.propsName}:<script>class Me extends React.Component{ render(){ return ( <div> <p>{this.props.props1}</p> <p>{this.props.props2}</p> <p>{this.props.props3}</p> </div> ); }};class Father extends React.Component{ render(){ return ( <Me props1={this.props.props1} props2={this.props.props2} props3={this.props.props3}/> ); }};ReactDOM.render( <Father props1=“a” props2=“b” props3=“c”/>,container);</script>如果你不想重复很多遍繁琐的{this.props.propsName},那你可以使用扩展运算符…表示取到所有的静态属性并且都使等于{this.props.propsName},所以我们的代码可以稍作简化:<script>class Me extends React.Component{ render(){ return ( <div> <p>{this.props.props1}</p> <p>{this.props.props2}</p> <p>{this.props.props3}</p> </div> ); }};class Father extends React.Component{ render(){ return ( <Me {…props}/> //????????使用扩展运算符进行简化{…props} ); }};ReactDOM.render( <Father props1=“a” props2=“b” props3=“c”/>,container);</script>React操作CSS此方法可以使你在<script>里更改、渲染CSS。不过使用React的JSX语法会和CSS语法有一点点不同,就一点点┑( ̄  ̄)┍因为刚开始接触,代码不难,所以直接先看示例代码吧;<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>React First Try</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Mycss extends React.Component{ render(){ var letterColor = { padding: 10, margin: 10, backgroundColor: this.props.thiscolor, color: “#333”, display: “inline-block”, fontFamily: “monospace”, fontSize: 32, textAlign: “center”, }; return (<div style={letterColor}>{this.props.children}</div>); } }; ReactDOM.render( <div> <Mycss thiscolor="#58B3FF”>B</Mycss> <Mycss thiscolor="#FF605F”>a</Mycss> <Mycss thiscolor="#FFD52E”>t</Mycss> <Mycss thiscolor="#49DD8E”>m</Mycss> <Mycss thiscolor="#AE99FF”>a</Mycss> <Mycss thiscolor="#FF6633”>n</Mycss> </div> , container ); </script></body></html>哇!!代码怎么看上去又有这么多的改动啊!!别慌张别慌张!其实和上一小节一样,只改动了一些内容在组件的render()和真实渲染的render()两个函数里组件render()里首先定义了一个虚拟CSS类,看上去符合CSS语法,但其实呢,他是一个JSX语法,仔细看,它就是一个用JSX语法写的神似CSS的对象。其中的一些区别如下:它不应该有px,px这种东西JSX会自动补充它不应该有分号;来表示这个属性结束了,请使用逗号,它应该把除了纯数字外的所有属性值都加上引号"“它应该使用驼峰命名法来表示CSS中使用连接号-的属性名:backgroundColor所以,在遵循了所有使用JSX语法描述CSS状态的规则之后,你就可以成功的定义一个虚拟CSS。接着,在组件的render()里调用它,像这样<div style={letterColor}>,style={虚拟CSS名}。在这里另一个知识点是,在定义虚拟CSS的backgroundColor时,它的参数值是一个变量this.props.thiscolor,同上一小节一样,在真实渲染render()的第一个参数里定义这个静态变量<Mycss thiscolor="#58B3FF”>。这样,就成功在CSS(虚拟的)里调用了其它地方的变量来确定属性值。效果、页面结构:值得注意的是,React处理的CSS是通过内联方式(标签中插入style属性)实现的小结这个时候,我们需要做一个小例子,来巩固下关于组件、CSS引入、props的概念我们想要实现的效果我们想要实现的效果就是,当你输入颜色代码,上面就能正确的展示颜色:分离组件在React的世界,一切都是组件,页面上所有的内容都是由一个个组件搭建起来的。你可以将结构划分为很小的组件,这样实现的功能就很详细。你也可以将结构划分为稍大的组件,功能就更集中。所以,像我们这样的小应用,下面的组件划分方法就足以满足要求:编写程序在分析完结构需要分成多少组件之后,可以开始构造代码首先,我们编写组件框架。其中每一个class就代表了我们分成的组件。在这里class ColorName表示文字部分,class Color表示颜色显示区,class Board表示用来承载这个应用的底板。每个组件都有一个render()函数用来之后渲染组件到DOM上。<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ } }; class Color extends React.Component{ render(){ } }; class Board extends React.Component{ render(){ } }; ReactDOM.render( <Board/>,container ); </script></body></html>上述步骤等于搭完了骨架,我们需要填充肌肉。写下,最终需要每个组件分别返回什么标签:ColorName组件返回一个<p>标签,用以展现颜色的色号Color组件返回一个<div>标签,用来显示颜色Board组件返回一个<div>标签,并且把上两个组件包在一起<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ return (<p>{this.props.colorName}</p>); } }; class Color extends React.Component{ render(){ return (<div id=“color”></div>); } }; class Board extends React.Component{ render(){ return ( <div> <Color colorName = {this.props.colorName}/> <ColorName colorName = {this.props.colorName}/> </div> ); } }; ReactDOM.render( <Board colorName="#f7a87d”/>,container ); </script></body></html>接下来我们只需要添加你想要的CSS就OK了,不过在添加CSS之前,我想对上一步骤简单解释:我们在渲染真实DOM时定义了一个静态属性colorName="#f7a87d”,经由组件Board传入组件ColorName、Color。最后通过每个组件各自的render()函数的return渲染在页面上。最后我们需要添加一些CSS帮页面穿点衣服,其中对CSS的引入使用了两种方法,使用React引入和引入外部CSS文件:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>Color</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script> <style> #board{ width: 300px; height: 400px; /* border: 1px solid red; */ border-radius: 3%; box-shadow: 3px 5px 7px 1px rgba(128,128,128,1); } #color{ height: 80%; border-radius: 3%; box-shadow: 1px 1px 6px 1px rgba(128,128,128,1); } </style></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class ColorName extends React.Component{ render(){ var ColorNameStyle = { fontSize: “2.5em”, fontFamily: “sans-serif”, fontWeight: “bold”, textAlign: “center”, margin: 17, }; return (<p style={ColorNameStyle}>{this.props.colorName}</p>); } }; class Color extends React.Component{ render(){ var colorStyle = { backgroundColor: this.props.colorName, }; return (<div style={colorStyle} id=“color”></div>); } }; class Board extends React.Component{ render(){ return ( <div id=“board”> <Color colorName = {this.props.colorName}/> <ColorName colorName = {this.props.colorName}/> </div> ); } }; ReactDOM.render( <Board colorName="#f7a87d”/>,container ); </script></body></html>使用state以上的各个步骤可以创建一个基本的静态页面,如果想要创建一个有点动态,看上不是死气沉沉的页面,那就一定需要state。正如之前提到的,props包含了所有的静态属性,state则包含了所有用于动态展示的属性。这时,我们需要一个例子我们的目标分离组件外面一个黑的长方形边框;内部一个黑色的底板;#5dffff的动态数字;三行文字编写代码编写代码框架:Times类表示变化的数字;Words表示三行灰色的文字;BlackBoard表示黑色的底板;Board表示最外面一圈黑边框<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Lightning</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ render(){ return (); } }; class Words extends React.Component{ render(){ return (); } }; class BlackBoard extends React.Component{ render(){ return (); } }; class Board extends React.Component{ render(){ return (); } }; ReactDOM.render( <Board/> ,container ); </script></body></html>然后我们需要添上返回的内容,我们就只看React的内容<script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ render(){ return (<h1>Strike Times</h1>); } }; class Words extends React.Component{ render(){ return ( <div> <p>lightning strike</p> <p>worldwide</p> <p>(since you loaded this outstanding)</p> </div> ); } }; class BlackBoard extends React.Component{ render(){ return ( <div> <Times/> <Words/> </div> ); } }; class Board extends React.Component{ render(){ return ( <div> <BlackBoard/> </div> ); } }; ReactDOM.render( <Board/> ,container );</script>将Strike Times变成动态,我们只需改变Times类:首先需要定义state:必须在constructor内定义this.state={}constructor(props){ super(props); this.state = { strike: 0, };}使用生命周期钩子,componentDidMount钩子里的内容会在页面渲染完成后被调用.在本例中,页面渲染完成后会调用一个计时器setInterval(),计时器中调用的函数请使用箭头函数,这样被调用的函数里的this才会被正确的指向当前类,其它调用方法会指向windowcomponentDidMount() { setInterval(() => this.addNumber(),1000);}定义你想调用的函数注意!!!如果你想修改state中的值,请必须使用this.setState()来修改!!addNumber(){ this.setState({ strike: this.state.strike + 100, });}最后,设定返回值,显示的内容为state中的strike值render(){ return (<h1>{this.state.strike}</h1>);}加上点样式<script type=“text/babel”> var container = document.querySelector("#container”); class Times extends React.Component{ constructor(props){ super(props); this.state = { strike: 0, }; } componentDidMount() { setInterval(() => this.addNumber(),1000); } addNumber(){ this.setState({ strike: this.state.strike + 100, }); } render(){ var strikeStyle = { margin: 0, padding: “55px”, color: “#5dffff”, fontSize: “60px”, } return (<h1 style={strikeStyle}>{this.state.strike}</h1>); } }; class Words extends React.Component{ render(){ var words = { fontFamily: “sans-serif”, margin: 0, padding: 0, }; var wordStyle = { wordNormal: { …words, color: “#999999”, fontSize: 33, }, wordBig: { …words, color: “#999999”, fontSize: 50, }, wordSmall: { …words, color: “#4d4d4d”, }, } return ( <div> <p style = {wordStyle.wordNormal}>lightning strike</p> <p style = {wordStyle.wordBig}>worldwide</p> <p style = {wordStyle.wordSmall}>(since you loaded this outstanding)</p> </div> ); } }; class BlackBoard extends React.Component{ render(){ return ( <div style = {this.props.style}> <Times/> <Words/> </div> ); } }; class Board extends React.Component{ render(){ var boardStyle = { board: { width: 300, height: 400, padding: 13, backgroundColor: “white”, border: “2px solid black”, }, blackboard: { height: “100%”, backgroundColor: “black”, borderRadius: “7%”, textAlign: “center”, lineHeight: “50px”, } }; return ( <div style={boardStyle.board}> <BlackBoard style = {boardStyle.blackboard}/> </div> ); } }; ReactDOM.render( <Board/> ,container );</script>使用JSX即使我们在之前的文章中已经开始使用了JSX这种React特别的语法,但是,我们还是应该为它专门开辟一个新的章节,因为,JSX、组件、组件生命周期是React的三大奠基核心(哈哈哈,当然是我的个人见解)。说到JSX,令人印象深刻的就是各种在js里添加html标签和出现在各个地方的{}在js里添加html标签在提倡 css样式、js行为、html标签 分离的时代,这样的设计别出心裁。主要是因为React的基础设施不是传统的html标签,而是各个组件。一个组件里包含了构成页面某一部分所需要的所有的 css样式、js行为、html标签 。 所以,遵循这样的思路,在js里添加html标签没什么稀奇的。像这样:var myname = <h1>Batman</h1>;function functionName(){ // your codes return <h1>Batman</h1>;}const me = ( <div> <h1>Batman</h1> <h2>hello gotham</h2> </div>);注意!!!JSX不能够将 多个html标签 直接赋给一个变量或者直接返回,需要将 多个html标签 包括在一个父元素中,就像上例第三个例子一样。{}在js里添加html标签对我们来说已经见怪不怪了,大括号{}的使用才是精髓。哈哈哈~~{}用于在React中的各个地方引用各种合理的JS表达式(valid JavaScript expression)。大括号里可以是变量user.username、表达式2+2、函数调用functionName(user)等。像这样:const name = ‘Josh Perez’;const element = <h1>Hello, {name}</h1>;const element = <img src={user.avatarUrl}></img>;const element = <h1>2+2={2+2}</h1>;function formatName(user) { return user.firstName + ’ ’ + user.lastName;}const user = { firstName: ‘Harper’, lastName: ‘Perez’};const element = ( <h1> Hello, {formatName(user)}! </h1>);ReactDOM.render( element, document.getElementById(‘root’));另外,还有双括号{{}}的写法,这种表达方式用于在JSX里内联样式。{{}}内的内容:对象的写法,将css里的;变成,属性名使用驼峰写法,css里-后面的第一个字母大写只会生效最后一个style,下例中只会生效style={gothamStyle}var myName = <h1 style={{color:“black”}} style={{fontSize:“25px”}} style={gothamStyle}>Batman</h1>;像这样:const myName = <h1 style={{color:“black”,fontSize:“25px”}}>Batman</h1>;关于更多React中操作CSS,你还可以浏览这篇文章:https://www.jianshu.com/p/850…JSX的优势防止XSS (cross-site-scripting)攻击。因为所有内容在被React渲染到页面上前都会先转成字符串小巧灵活。JSX本质就是Javascript,所以,JSX可以被放在任何一个地方。再加上JSX里的内容非常丰富。结合React的设计思想,JSX非常好用。当然JSX还可以撰写css内容,详细可以参见之前章节:React操作CSS使用JSX的一个例子只要使用React搭建网站必然需要用到JSX,额,虽然官方是这样表示的:Well我们还是快速的过一遍这个例子我们要实现的目标几个圆圈过1秒就变颜色,颜色随机从颜色库里选取完整代码其实很简单,Circle组件负责改变颜色的行为,CreateCircle组件负责定义样式并渲染这些圆圈。然后因为一直是动态的,所以,使用Circle组件的state,每个一段时间setInterval都会调用changeColor函数,来改变state里的内容,改变之后React会重新渲染页面被改动的部分。值得注意的是,在这个例子中,JSX被运用在任何一个位置,可以被压到数组中去colorarray.push(<CreateCircle bgColor={colors[random]} key={i}/>)被渲染render(){ return (<div>{this.state.colorArray}</div>);};撰写、引用cssclass CreateCircle extends React.Component{ render(){ var circleStyle = { padding: 10, margin: 20, display: “inline-block”, backgroundColor: this.props.bgColor, borderRadius: “50%”, width: 100, height: 100, }; return (<div style={circleStyle}></div>); }};注意!!!在React中使用key={}属性来唯一标识一个组件<CreateCircle key={i}/>完整代码:<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Lightning</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.getElementById(“container”); var colors = ["#393E41”,"#E94F37”,"#1C89BF”,"#A1D363”,"#85FFC7”,"#297373”,"#FF8552”,"#A40E4C”]; class Circle extends React.Component{ constructor(props){ super(props); this.state = { colorArray: [], }; }; changeColor(){ var colorarray = []; this.setState({ colorArray: [], }); for(var i=0;i < colors.length;i++){ var random = Math.floor(Math.random()*colors.length); colorarray.push(<CreateCircle bgColor={colors[random]} key={i}/>) this.setState({ colorArray: colorarray, }); } }; componentDidMount(){ setInterval(() => this.changeColor(),1000); }; render(){ return (<div>{this.state.colorArray}</div>); }; }; class CreateCircle extends React.Component{ render(){ var circleStyle = { padding: 10, margin: 20, display: “inline-block”, backgroundColor: this.props.bgColor, borderRadius: “50%”, width: 100, height: 100, }; return (<div style={circleStyle}></div>); } }; ReactDOM.render( <Circle/> ,container ) </script></body></html>React中的事件事件的意义不用多说,事件是页面与用户交互的唯一途径,人机交互大部分还是通过鼠标和键盘吧,当然还有像手写板、麦克风、摄像头等设备,但截至今日前端貌似没有什么权限,不然安全性就太差了。在React中,事件的绑定大致和原生网页相似,大概也就是命名方式不同和this的指向不同这两点区别。可以参考:https://reactjs.org/docs/hand…在React中绑定事件直接绑定class Button extends React.Component{ render(){ return (<button onClick=“console.log(‘Hello gotham’)">Click me!</button>) }}WHAT??这不是和原生的一模一样吗?是呀,只是在命名上采用的是React喜爱的驼峰Camel-Case命名法,原生的都是小写。但这种方法多老式。间接绑定class Button extends React.Component{ consoleLog(){ console.log(“Hello gotham”); } render(){ return (<button onClick={this.consoleLog}>Click me!</button>) }}将函数拿到外面去,然后在元素的事件上绑定这个函数,绑定的时候使用JSX的{}并且一定加上this,表示绑定的是这个组件里的函数。超级间接绑定class Inner extends React.Component{ render(){ return (<button onClick={this.props.clickHandler}>Click me!</button>) }}class Outer extends React.Component{ consoleLog(){ console.log(“Hello gotham”); } render(){ return (<Inner clickHandler={this.consoleLog}/>) }}哈哈哈,这是什么鬼?就是利用了React的props,把函数绑定在一个props上,本例中是clickHandler,然后渲染了新组件,在新组件中,可以使用this.props来调用这个函数。简单来说就是,将函数从父组件通过props传递到了子组件。this的指向在React中,绝大部分的this都指向组件本身。但是,在自定义的函数中,this是没有指向的,所以会有this is undefined的报错,尤其是自定义的函数需要引用函数外组件内的其它资源的时候。像下面这样写是会报错的:我们想要点击Hello gotham按钮调用greeting函数,greeting函数会调用gotham函数打印Hello gotham字样。但是,greeting函数里的this没有指向,所以会出现上面的报错。class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ return (<button onClick={this.greeting}>Hello gotham<button/>) }}所以,如果想要在自定义函数中调用同组件其它资源,你有下面3中方法来绑定this:constructor中绑定class Welcome extends React.Component{ constructor(props){ super(props); this.greeting = this.greeting.bind(this); ????这句是绑定 } gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ return (<button onClick={this.greeting}>Hello gotham<button/>) }}内联式绑定class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ ????????????????????????这里是绑定 return (<button onClick={this.greeting.bind(this)}>Hello gotham<button/>) }}内联式箭头函数绑定class Welcome extends React.Component{ gotham(){ console.log(“Hello gotham”); } greeting(){ this.gotham(); } render(){ ????????????????????????????????????????????????这里是绑定 return (<button onClick={(e) => this.greeting(e)}>Hello gotham<button/>) }}关于绑定this还可以参考:https://www.jianshu.com/p/95a…合成事件SyntheticEventReact中的合成事件可以对应为通常函数中的事件对象eventfunction gotham(event){ // your codes}e…这个功能有点多,你可以自己打印出来看看呀,或者看看官方文档:https://reactjs.org/docs/even…这里只贴出来关于鼠标和键盘事件:鼠标事件boolean altKeyboolean ctrlKeyboolean shiftKeyboolean metaKeynumber buttonnumber buttonsnumber clientXnumber clientYboolean getModifierState(key)number pageXnumber pageYDOMEventTarget relatedTargetnumber screenXnumber screenY适用于如下事件:onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp键盘事件boolean altKeynumber charCodeboolean ctrlKeyboolean getModifierState(key)string keynumber keyCodestring localenumber locationboolean metaKeyboolean repeatboolean shiftKeynumber which适用于如下事件:onKeyDown onKeyPress onKeyUp关于事件的小例子我们的目标点击加号按钮数字加1,按住shift点击加号,数字加10实现思路分割组件。底板、数字、按钮点击按钮数字变化,所以,将资料存放于数字组件,并且通过数字组件调用按钮键盘事件的合成事件中,能够监听shift键是否被按下抛开样式的完整代码其它的无关紧要,注意Show组件内的increase函数,我们可以看到合成事件e.shiftKey和{this.increase.bind(this)}的使用<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <title>react-event</title> <script src=“https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src=“https://unpkg.com/babel-standalone@6/babel.min.js"></script></head><body> <div id=“container”></div> <script type=“text/babel”> var container = document.querySelector("#container”); class Button extends React.Component{ render(){ return (<button onClick={this.props.clickHandler}>+</button>) } } class Show extends React.Component{ constructor(props){ super(props); this.state = { number: 0, }; } increase(e){ var num = this.state.number; if(e.shiftKey){ num += 10; }else{ num += 1; } this.setState({ number: num, }); } render(){ return ( <div> <p>{this.state.number}</p> <Button clickHandler={this.increase.bind(this)}/> </div> ) } } class Board extends React.Component{ render(){ return ( <div> <Show/> </div> ); } }; ReactDOM.render( <Board/>, container ) </script></body></html>组件的生命周期LifecycleReact创造出来组件,同时也给组件配上了生命周期,用来更好的控制组件,这也是React的一大优势。组建的生命周期可以参考这个:https://reactjs.org/docs/reac…。往下多翻翻~~这个参考资料也非常棒:https://www.w3cplus.com/react…常用生命周期componentDidMount()componentDidUpdate()componentWillUnmount()不常用且慎用的生命周期shouldComponentUpdate()static getDerivedStateFromProps()getSnapshotBeforeUpdate()static getDerivedStateFromError()componentDidCatch()消失的生命周期消失的生命周期不理他。React Router官方文档:https://reacttraining.com/rea…github:https://github.com/ReactTrain…React Router就把他看作是一个插件吧,中文名:React路由。