面向组件编程
react元素
React 元素是不可变对象。一旦被创建,你就无法更改它的子元素或者属性。
一个元素就像电影的单帧:它代表了某个特定时刻的 UI。
更新 UI 唯一的方式是创建一个全新的元素,并将其传入 ReactDOM.render()
data-reactroot 表明当前元素是 该组件的顶层标签
react组件概念理解
组件,从概念上类似于 JavaScript 函数。它接受任意的入参(即 “props”),并返回用于描述页面展示内容的 React 元素。
- 自定义的标签: 组件类(函数)/标签
- 组件名称必须以大写字母开头。
- React 会将以小写字母开头的组件视为原生 DOM 标签
组件定义方式:
1.定义组件最简单的方式就是编写 JavaScript 函数:
(简单组件)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “props”(代表属性)对象与并返回一个 React 元素。
这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。
2.还可以使用 ES6 的 class 来定义组件:
(复杂组件)
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
这两个组件在 React 里是等效的
渲染组件:
ReactDOM.render(<MyComponent />, document.getElementById('example1'))
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
注意
- 组件名必须首字母大写
- 虚拟 DOM 元素只能有一个根元素
- 虚拟 DOM 元素必须有结束标签
render()渲染组件标签的基本流程
- React 内部会创建组件实例对象
- 得到包含的虚拟 DOM 并解析为真实 DOM
- 插入到指定的页面元素内部
组件三大属性 1: state
- 组件被称为"状态机", 页面的显示是根据组件的state属性的数据来显示
- 初始化指定:
constructor() {
super()
this.state = {
stateName1 : stateValue1,
stateName2 : stateValue2
}
}
- 读取显示:
this.state.stateName1
- 更新状态–>更新界面 :
this.setState({stateName1 : newValue})
例:需求: 自定义组件, 功能说明如下
1. 显示h2标题, 初始文本为: 你喜欢我
2. 点击标题更新为: 我喜欢你
//1.定义组件
class Like extends React.Component{
constructor (props){
super(props)
//初始化状态
this.state={
isLikeMe:false
}
//将新增的方法中的this强制绑定为组件对象
this.handleClick=this.handleClick.bind(this);
}
//新添加的方法里面的this默认的不是组件对象,而是undefined
handleClick(){
//得到状态并取反
const isLikeMe = !this.state.isLikeMe;
//更新状态
this.setState({isLikeMe})
}
render(){
//读取状态
const {isLikeMe} = this.state
return <h2 onClick={this.handleClick}>{isLikeMe?'你喜欢我':'我喜欢你'}</h2>
}
}
//2.渲染组件标签
ReactDOM.render(<Like/>,document.getElementById('example'))
组件三大属性 2: props
- 所有组件标签的属性的集合对象
- 给标签指定属性, 保存外部数据(可能是一个function)
- 在组件内部读取属性:
this.props.propertyName
- 作用: 从目标组件外部向组件内部传递数据
- 对props中的属性值进行类型限制和必要性限制
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number.isRequired
}
- 默认属性值
Person.defaultProps = { name: 'Mary' }
- 组件类的构造函数
constructor (props) {
super(props) console.log(props)
// 查看所有属性
}
- 扩展属性: 将对象的所有属性通过props传递
<Person {...person}/>
例:需求: 自定义用来显示一个人员信息的组件
1). 姓名必须指定
2). 如果性别没有指定, 默认为男
3). 如果年龄没有指定, 默认为 18
//定义组件
function Person(props){
return(
<ul>
<li>姓名:{props.name}</li>
<li>年龄:{props.age}</li>
<li>性别:{props.sex}</li>
</ul>
)
}
//指定默认属性值
Person.defaultProps = {
sex:'男',
age:18
}
//指定属性值的类型和必要性
Person.propTypes={
//姓名的类型是字符串类型,且必须
name:PropTypes.string.isRequired,
age:PropTypes.number,
sex:PropTypes.string
}
//渲染组件标签
const p1 ={
name:"Tom",
age:18,
sex:"男"
}
ReactDOM.render(<Person name={p1.name} age={p1.age} sex={p1.sex}/>,document.getElementById("example1"))
//默认属性值
const p2 ={
name:"Jack",
}
ReactDOM.render(<Person name={p2.name} age={p2.age} sex={p2.sex}/>,document.getElementById("example1"))
组件的 props 和 state 属性区别
- state: 组件自身内部可变化的数据
- props: 从组件外部向组件内部传递数据, 组件内部只读不修改
组件三大属性 3: refs 与事件处理
- 组件内的标签都可以定义 ref 属性来标识自己
a.<input type="text" ref={input => this.msgInput = input}/>
b. 回调函数在组件初始化渲染完或卸载时自动调用 - 在组件中可以通过 this.msgInput 来得到对应的真实 DOM 元素
- 作用: 通过 ref 获取组件内容特定标签对象, 进行读取其相关数据
例:需求: 自定义组件, 功能说明如下:
- 点击按钮, 提示第一个输入框中的值
- 当第 2 个输入框失去焦点时, 提示这个输入框中的值
/*
需求: 自定义组件, 功能说明如下:
1. 界面如果页面所示
2. 点击按钮, 提示第一个输入框中的值
3. 当第2个输入框失去焦点时, 提示这个输入框中的值
*/
//定义组件
class MyComponent extends React.Component{
constructor(props){
super(props)
this.showInput = this.showInput.bind(this)
}
//show功能定义
showInput(){
const input = this.refs.content;
alert(input.value);
//alert(this.input.value); 对应版本二
}
handleBlur(event){
alert(event.target.value)
}
render(){
return(
<div>
<input type="text" ref="content"/>
// 版本二 <input type="text" ref={input=>this.input = input}/>
<button onClick={this.showInput}>提示输入</button>
<input type="text" placeholder="失去焦点提示内容" onBlur={this.handleBlur}/>
</div>
)
}
}
//渲染组件标签
ReactDOM.render(<MyComponent/>,document.getElementById("example"))
事件处理
- 通过 onXxx 属性指定组件的事件处理函数(注意大小写)
a. React 使用的是自定义(合成)事件, 而不是使用的原生 DOM 事件
b. React 中的事件是通过事件委托方式处理的(委托给组件最外层的元素) - 通过 event.target 得到发生事件的 DOM 元素对象
<input onFocus={this.handleClick}/>
handleFocus(event) {
event.target
//返回 input 对象
}
强烈注意
- 组件内置的方法中的 this 为组件对象
- 在组件类中自定义的方法中 this 为 null
a. 强制绑定 this: 通过函数对象的 bind()
b. 箭头函数(ES6 模块化编码时才能使用)