React

网页总是一个链接着另一个的,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>标签。注意!!!组件名首字母必须大写!!!引用组件注意代码<组件名/>,一个符号都不能错的!!!

使用props

props用来获取组件的静态属性,可以先看下面的一个小例子:
<!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才会被正确的指向当前类,其它调用方法会指向window
componentDidMount() {
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>);
};

撰写、引用css
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>);
}
};

注意!!!在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…
合成事件SyntheticEvent

React中的合成事件可以对应为通常函数中的事件对象event
function gotham(event){
// your codes
}
e…这个功能有点多,你可以自己打印出来看看呀,或者看看官方文档:https://reactjs.org/docs/even…
这里只贴出来关于鼠标和键盘事件:

鼠标事件
boolean altKey
boolean ctrlKey
boolean shiftKey
boolean metaKey
number button
number buttons
number clientX
number clientY
boolean getModifierState(key)
number pageX
number pageY
DOMEventTarget relatedTarget
number screenX
number screenY
适用于如下事件:
onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp

键盘事件
boolean altKey
number charCode
boolean ctrlKey
boolean getModifierState(key)
string key
number keyCode
string locale
number location
boolean metaKey
boolean repeat
boolean shiftKey
number 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>
组件的生命周期Lifecycle

React创造出来组件,同时也给组件配上了生命周期,用来更好的控制组件,这也是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路由。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理