1. React 特点
Declarative(声明式编码)
Component-Based(组件化编码)
Learn Once, Write Anywhere(支持客户端与服务器渲染)
高效
单向数据流
2.JSX语法
2.1 概念:
用JavaScript来描述html
JSX 就是用来声明 React 当中的元素
const myelement = <h1>hello</h1>;
要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:
ReactDom.render(myelement,document.getElementById('example'));
2.2 注意
由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。
2.3 实例
用一个div标签包裹住多个html标签,下面实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。
ReactDOM.render(
<div>
<h1>菜鸟教程</h1>
<h2>欢迎学习 React</h2>
<p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p>
</div>
,
document.getElementById('example')
);
2.4独立文件
可以把React JSX代码放在一个独立的js文件上,然后再HTML文件中引入该文件。
例如创建一个 helloworld_react.js 文件:
ReactDOM.render(
<h1>Hello</h1>,
document.getElementById('example')
);
在 HTML 文件中引入该 JS 文件:
<body>
<div id="example"></div>
<script type="text/babel" src="helloworld_react.js"></script>
</body>
2.5 JavaScript 表达式
我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。实例如下:
ReactDOM.render(
<div>
<h1>{1+1}</h1>
</div>
,
document.getElementById('example')
);
在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。
ReactDOM.render(
<div>
<h1>{i == 1 ? 'True!' : 'False'}</h1>
</div>
,
document.getElementById('example')
);
2.6 样式
React 推荐使用内联样式,会在指定元素数字后自动添加 px。
var mystyle={
font-size:20;
color:'#FF0000'
};
ReactDOM.render(
<h1 style = {mystyle}>hello</h1>,
document.getElementById('example')
);
2.7 数组
JSX 允许在模板中插入数组,数组会自动展开所有成员:
var arr=[
<h1>hello</h1>,
<h2>world</h2>
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
3.组件
3.1 定义组件
函数定义
function HelloMessage(props){
return (<h1>hello</h1>)
}
类定义
class Hello extends React.Component{
render(){
return(
<h1>world</h1>
)
}
}
注意
原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头。
组件类只能包含一个顶层标签。
const element = <HelloMessage /> 为自定义组件。
3.2 向组件传递参数
使用 this.props 对象
function HelloMessage(props){
return (<h1>hello {props.name} </h1>)
}
const element = <HelloMessage name="kate"/>
ReactDOM.render(element,document.getElementById('example'))
注意
class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
3.3 复合组件
通过创建多个组件来合成一个组件
function Name(props){
return (<h1>姓名:{props.name}</h1>);
}
function Age(props){
return (<h1> 年龄:{props.age}</h1>);
}
function People(){
return(
<div>
<Name name="kate"/>
<Age age="12"/>
</div>
);
}
ReactDOM.render(<People />,document.getElementById('example'));
4.state
4.1 概念
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
创建一个类,在render()方法中,使用this.state显示当前时间。
添加一个类构造函数来初始化this.state,类组件应始终使用props调用基础构造函数。
class Clock extends React.Component{
constructor(){
super(props);
this.state={
data:new Data();
};
}
render(){
return(
<div>
<h1>当前时间:{this.state.data.toLocaleTimeString()}</h1>
</div>
)
};
}
ReactDOM.render(<Clock />,document.getElementById('example'));
5.props
5.1 默认属性
props是不可变的,子组件只能通过props来传递数据。
可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
class HelloMessage extends React.Component{
render(){
return(
<h1>hello {this.props.name}</h1>
)
};
}
HelloMessage.defaultProps={
name:'kate'
}
5.2 state和props组合使用
在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。
class Website extends React.Component{
constructor(props){
super(props);
this.state={
name:"百度",
site:"www.baidu.com"
}
}
render(){
return(
<div>
<Name name={this.state.name}/>
<Link site={this.state.site}/>
</div>
)
};
}
class Name extends React.Component{
render(){
return(
<h1>{this.props.name}</h1>
);
}
}
class Link extends React.Component{
render(){
return(
<a href={this.props.site}>{this.props.site}</a>
);
}
}
ReactDOM.render(<WebSite />,document.getElementById('example'));
6.生命周期
6.1 组件的三个生命周期
Mounting:已插入真实DOM
Updating:正在被重新渲染
Unmounting
6.2 生命周期的方法有:
componentWillMount 在渲染前调用,在客户端也在服务端。
componentDidMount : 在第一次渲染后调用,只在客户端。可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
componentWillUnmount在组件从 DOM 中移除之前立刻被调用。
6.3 将生命周期方法添加到类中
在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要.
每当 Clock 组件第一次加载到 DOM 中的时候,我们都想生成定时器,这在 React 中被称为挂载。
每当 Clock 生成的这个 DOM 被移除的时候,我们也会想要清除定时器,这在 React 中被称为卸载。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>现在是 {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('example')
);
案例解析:
componentDidMount() 与 componentWillUnmount() 方法被称作生命周期钩子。
在组件输出到 DOM 后会执行 componentDidMount() 钩子,我们就可以在这个钩子上设置一个定时器。
this.timerID 为定时器的 ID,我们可以在 componentWillUnmount() 钩子中卸载定时器。
7.事件
7.1 语法
命名采用驼峰式写法。
如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)。
<button onClick={activateLasers}>
激活按钮
</button>
不能使用返回 false 的方式阻止默认行为, 你必须明确的使用 preventDefault。
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('链接被点击');
}
return (
<a href="#" onClick={handleClick}>
点我
</a>
);
}
7.2 为类的方法绑定this
案例:让用户切换开关状态的按钮
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state={
isToggleOn:true
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
this.setState(prevState=>({
isToggleOn: !prevState.isToggleOn
}))
}
render(){
return(
<button onClick={this.handleClick} >{this.state.isToggleOn?'on':'off'}</button>
)
}
}
export default App;