学习笔记:React组件
一、前沿
React主要的作用是提高前端开发MVC架构中的View开发效率。提高前端页面的代码复用率、简化前端数据绑定、提升前端页面的渲染性能等工作。
在前端页面代码(html、css等)的复用上,React采用的是组件化,通过组件化封装前端页面代码,做到可复用可移植。
因此,对于学习React,对于组件的掌握至关重要,可以说组件是react的主要内容。
二、组件
2.1、定义一个组件
- 函数组件,即使用js函数定义。
// 使用props向组件传递参数
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="tom"/>;
//调用函数软如
ReactDOM.render(element, document.getElementById('root'));
- class组件,使用ES6的class语法来定义一个组件:
class HelloWorld extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}
2.2、组件的样式:
- 组件支持三种样式方案:内联样式、对象样式、选择器样式
<head>
<style>
.pStyle {
font-size:30px;
}
</style>
</head>
var hStyle = {
backgroundColor: "green",
color: "red"
}
var ShowMessage = React.createClass({
render: function() {
return (
<div style={{ backgroundColor:"yellow", borderWidth:5, borderColor:"brack", broderStyle:"solid" }}> // 内联样式
<h1 style={hStyle}>{this.props.firstRow}</h1> // 对象样式
<p className="pStyle">{this.props.secondRow}</p> // 选择器样式,注意因为Class为关键字,只能ClassName指定样式。
</div>
);
}
});
ReactDOM.render(
<ShowMessage firstRow="你好" secondRow="小豆豆" />,
document.getElementById("container")
);
注意:在React和HTML5中设置样式时的书写格式是有区别的
- 1、HTML5以;结尾。React以,结尾
- 2、HTML5中key、value都不加引号。React中属于Javascript对象,key的名字不能出现"-",需要使用驼峰命名法。 如果value为字符串,需要加引号。
- 3、HTML5中,value如果是数字,需要带单位。React中不需要带单位
2.3、复合组件
支持将多个自定义组件合成一个组件,方法和定义组件时候聚合HTML标签一样。
render: function() {
return (
<HelloWorld>
<NameLbl></NameLbl >
</HelloWorld >
);
}
2.4、使用规范
- 组件名大写字母开头,遵守驼峰命名法。
- 核心代码:每个组件类必须实现自己的render方法,该方法返回定义好的组件模板(即JSX标签块)。
- 注意:组件类只能包含一个顶级标签。
三、组件的声明周期
3.1、组件的三种状态:
-
Mounting
:组件挂载,已插入真实 DOM -
Updating
:组件更新,正在被重新渲染 -
Unmounting
:组件销毁,已移出真实 DOM
3.2、组件的声明周期函数
- 组件的四个阶段:创建 -> 实例化 -> 更新 -> 销毁。
a、组件挂载:
- componentWillMount
在渲染前调用,在客户端也在服务端。 - componentDidMount :
在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
b、组件更新:
- componentWillReceiveProps
在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。 - shouldComponentUpdate
返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。 - componentWillUpdate
在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。 - componentDidUpdate
在组件完成更新后立即调用。在初始化时不会被调用。
c、组件移除:
- componentWillUnmount
在组件从 DOM 中移除之前立刻被调用。
d、与组件的props、state有关:
getDefaultProps 设置props属性的默认值
getInitialState 设置state属性的初始值。
- 3.3、例子
// ES6语法,class
class Content extends React.Component {
componentWillMount() {
console.log('Component WILL MOUNT!')
}
componentDidMount() {
console.log('Component DID MOUNT!')
}
componentWillReceiveProps(newProps) {
console.log('Component WILL RECEIVE PROPS!')
}
shouldComponentUpdate(newProps, newState) {
return true;
}
componentWillUpdate(nextProps, nextState) {
console.log('Component WILL UPDATE!');
}
componentDidUpdate(prevProps, prevState) {
console.log('Component DID UPDATE!')
}
componentWillUnmount() {
console.log('Component WILL UNMOUNT!')
}
render() {
return (
<div>
<h3>{this.props.myNumber}</h3>
</div>
);
} // render
} // class
// 组件渲染
ReactDOM.render(
<div>
<Button />
</div>,
document.getElementById('example')
);
四、Props
- 组件自身的属性值,一般用于嵌套的内外层组件中,负责传递数据(通常是父组件向子组件传递数据)。
实例:定义HelloWorld组件,里面通过props接收父组件的属性title。
class HelloWorld extends React.Component {
// 渲染核心函数
render() {
return (
<div>
<h1>Hello, {this.props.title} !</h1>
<Clock></Clock>
<TapButton></TapButton>
</div>
)
}
}
// 使用HelloWorld组件
< HelloWorld title='xxx'></HelloWorld>
-
Props 的只读性,即组件内不可设置props的值,如
this.props.title = 'xxx'; //不允许
-
Props是由外部传送的,即使用组件的时候传入。
-
...this.props
Props提供的语法糖,可以将父组件的全部属性都复制给子属性。
class Link extends React.Component {
render() {
return <a {...this.props}>{this.props.name}</a>;
}
}
ReactDOM.render(
<Link href='https://www.baidu.com' name='tom'>,
document.getElementById('example')
);
-
this.props.children
表示组件的所有子节点。 -
propsType
属性验证
校验父组件传入的值是否符合要求,如参数是不是某种参数类型。 -
getDefaultProps()
,设置属性默认值。
class Link extends React.Component {
getDefaultProps() {
return {
title:"默认标题"
}
},
render() {
return <a>{this.props.title}</a>;
}
}
五、State
- 实例:定义组件Clock,实现按秒显示当天日期时间的功能。
在构造器constructor ()
内,定义state
的date
属性。然后在组件挂载的时候,即周期函数componentDidMount()
初始化定时器,在定时器函数timerHandler()
内,给你更新state
的date
值,页面自动刷新。
class Clock extends React.Component {
// 构造函数
constructor(props) {
super(props);
// 定义state里面的 date 属性
this.state = {date: new Date()};
}
// 声明周期
componentDidMount() {
this.timer = setInterval(
() => this.timerHandler(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timer);
}
// 渲染核心函数
render() {
return (
<h2> today is {this.state.date.toLocaleTimeString()}</h2>
)
}
// custom
timerHandler() {
// 更新 state.date 属性
this.setState({
date: new Date()
});
}
}
-
更新完组件的
state
后,React框架会根据新的State需要自动的重新渲染用户界面。 -
State只能由组件内部改变的,外部没办法修改。
-
不能直接修改State,需要通过
setState()
方法。
例如this.state.comment = 'Hello'; //错误
this.setState({comment: 'Hello'});
-
State 的更新可能是异步的。
出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用。 -
State 的更新会被合并,即多个
this.setState()
合并成一个函数。
当你调用 setState() 的时候,React 会把你提供的对象合并到当前的 state。