1.1-React核心概念
Create by fall on 2021-11-10 Recently revised in 2022-03-28
JSX
// JSX 代码:
const element = (
<h1 className="reactTitle">
Hello World
</h1>
)
// 上面的语法是 JSX 实现 DOM 相当于 React 的
const element = React.crateElement(
'h1',
{className:'greeting'},
'Hellow World'
)
// 原生的代码(如果要渲染到文档中,三者是等价的)
const dom = document.createElement('h1')
dom.innerHtml = `Hello World`
const node = document.querySelector('.reactTitle')
node.appendChild(dom)
声明组件的方式
一般来讲,所有的组件都有两种声明方式,函数式组件声明和类式组件声明。
两种声明方式,对应的也有各自的使用方式。
更推荐使用函数式组件。
函数式组件
- 函数名称必须大写
- 调用时以标签方式调用,并且开头大写
- 组件参数为 props
// function 创建组件
function Welcome(props){
return (<h1>你好啊{props.name}</h1>)
}
// 特点:接受唯一带有数据的 props (properties),并且返回了一个 React 元素,本质上就是 JavaScript 函数
更多函数式组件的内容可以查看 Hooks 章节,本章节不做具体介绍
类式组件
- 必须继承 React 的内置类
Component
- 必须包含
render
方法 - 构造函数
constructor
的参数为props
,使用props
时,必须调用super(props)
// class 创建组件
class Welcome extends React.component{
constructor(props){
super(props)
}
render(){
return <h1>Hello,{this.props.name}</h1>
}
}
const element = <Welcome name="Sara"/>;
ReactDOM.render(
element,
document.getElementById('root')
)
三大属性
- state 用于表示当前组件的属性
- props 表示父组件传过来的内容
- ref 表示引用,即引用的那个 React DOM
state
子组件私有数据
声明只有子组件可以使用的数据
class Clock extends ReactDOM.Compont{
// 通过 constructor 将 props 传递到父类的构造函数中
constructor(props){
super(props)
this.state = {
name:'刘华强'
}
}
render(){
// setState 用来设置 state
const state = this.state
state.age = 23
this.setState(state)
return(
<div>
<strong>姓名:{this.state.name}</strong>
<span>年龄:{this.state.age}</span>
</div>
)
}
}
props
详细请看第 2 章
父组件传递数据
// 子组件
class BiteMe extends React.Component{
render(){
return (
<div style={{border:'1px solid black',backgroundColor:'pink'}}>
<div>人们不懂的是{this.props.chelie}</div>
</div>
)
}
}
// 父组件
class Father extends React.Component{
render(){
return(
<div>
<h1>人们从来不懂</h1>
<BiteMe chelie="硫化铅"/>
</div>
)
}
}
ref
获取元素的值
class MyComponent extends React.Component{
constructor(props){
super(props)
this.inputRef = React.createRef() // 首先创建一个可以存放 ref 的容器
}
render(){
return (
<div>
<input type="color" ref={this.inputRef}></input>
</div>
)
}
componentDidMount(){
console.log(this.inputRef)
}
}
条件渲染和列表
防止组件渲染
// 函数式组件
function WarningBanner(){
if(props.warn===false){
return null // 通过返回 null 可以使 function 组件不被渲染
}
return (<h1 class="warn">当前界面出现问题</h1>)
}
// 类式组件
class WarnBanner extends React.Component{
constrcutor(props){
super(props)
this.state = {warn:props.warn}
}
}
在组件的
render
方法中返回null
并不会影响组件的生命周期。
组件的事件绑定
列表
当传入数组作为参数,并且参数都为模板字符串时,就可以通过 React
进行渲染。
import React from 'react'
class MyComopnent extends React.components{
return (
<div>
<h3>谁能给解释一下?</h3>
{[<div>你这个不行</div>,<div>啥是三不行</div>]}
</div>
);
}
// 对于列表要进行多个优化,传入 key
const list = ['今天吃了没','今天喝了没','今天emo了没']
class ListComponent extends React.components{
return (
<div>
{list.map(item=>(<div key={item}>{item}</div>))}
</div>
)
}
生命周期
class 组件的生命周期
- constructor:构造
- getDerviderStateFromProps:构造后渲染前执行
- render:渲染
- componentDidMount:插入到 DOM 树后
class React.Component{
constructor(props){
super(props)
}
render(){
return(<h1>渲染</h1>)
}
getDerivedStateFromProps(nextProps,currentState){
}
componentDidMount(){
// componentDidMount() 里直接调用 setState()。它将触发额外渲染,也就是两次 render,不过问题不大,主要还是理解。
}
shouldComponentUpdate(){
// 这是一个优化方案,通过返回 true 和 false 表明是否触发新的渲染,通过条件组织不渲染的情况,首次渲染、调用 forceUpdate 会跳过触发
if(condition){
return true
}
// PureComopnent 也默认实现了该钩子,将 porps 和 state 进行钱比较,确定是否是触发更新。
return false
}
getSnapshotBeforeUpdate(){
// 确定更新,在更新前调用该钩子
}
componentDidUpdate(){
// 更新后执行
}
componentWillUnmount(){
// 对于事件的解绑,消除定时器,取消订阅
}
}