<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
// 1、创建虚拟dom
// jsx 中,这里不需要加引号,因为不是字符串,而是节点
let VDOM = <h1>hello react</h1>
// 2、渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"))
script>
body>
法一:js (不需要引入babel.min.js转换文件)
React.createElement("标签名", 属性对象,”标签内容“)
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script type="text/javascript">
// 1、创建虚拟dom
// createElement 是react中创建节点的方法,接受3个参数:1、标签名(字符串),2、属性(对象),3、标签内容(字符串)
// 如果要创建嵌套的节点,需要将内容 3 替换为 createElement 创建的节点
// 以上是js创建虚拟节点的方法,而jsx只需要按照 html 方式,将节点罗列
// let VDOM = React.createElement("h1", { id: "react" }, "hello react");
let VDOM = React.createElement("h1", { id: "react" }, React.createElement("span", { class: "title" }, "hello react"));
// 2、渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"))
script>
body>
法二:jsx
ReactDOM.render(虚拟DOM, 目标节点)
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
// 1、创建虚拟dom
// jsx 中,这里不需要加引号,因为不是字符串,而是节点
let VDOM = (
<h1 id="react">
<span className="title">hello react</span>
</h1>
)
// 2、渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"))
script>
body>
jsx 创建虚拟dom,其实是 js 创建虚拟dom的语法糖,内部使用的仍然是 js 语法。
<body>
<style>
.title {
background-color: aqua;
width: 400px;
}
style>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
let myId = "react",
myContent="hello react";
let VDOM = (
<div>
<h1 className="title" id={myId}>
<span style={{fontSize: "40px", color: "red"}}>{myContent}</span>
</h1>
<h1 className="title" id={`${myId}-copy`}>
<span style={{fontSize: "40px", color: "red"}}>{myContent}</span>
</h1>
</div>
)
ReactDOM.render(VDOM, document.getElementById("test"))
script>
body>
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
let arr = ["angular","vue","react"]
let VDOM = (
<div>
<h1>前端js框架</h1>
<ul>
{
arr.map((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
</div>
)
ReactDOM.render(VDOM, document.getElementById("test"))
script>
body>
注意区分:js 语句(代码)与 js表达式
当应用的js都以模块来编写,这个应用就是一个模块化的应用
当应用是以多组件的方式实现,这个应用就是一个组件化的应用
ReactDOM.render( , document.getElementById("test"))
将函数组件渲染到页面上
ReactDOM.render(MyComponent(), document.getElementById("test"))
将组件渲染到页面上<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
// 1、创建函数式组件(首字母必须大写)
function MyComponent () {
console.log(this) // 这里的 this 是 undefined ,因为 babel 将jsx编译为js后,开启了严格模式
return <h1>使用函数定义的组件(适用于简单组件的定义)</h1>
}
// 2、渲染组件到页面(有两种写法)
// 2.1 使用组件标签(首字母要大写,小写的话会默认匹配html标签),React 内部发现是函数式组件,会自动调用该函数
// 2.2 直接调用函数方法
// ReactDOM.render( , document.getElementById("test"))
ReactDOM.render(MyComponent(), document.getElementById("test"))
/*
执行 ReactDOM.render( , document.getElementById("test"))后发生了什么?
1、React 解析组件标签,找到 MyComponent 组件
2、发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DON,随后呈现到页面中
*/
script>
body>
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sperak() {
console.log(`我叫${this.name}, 今年${this.age}岁`)
}
}
// Student 类继承 Person 类
class Student extends Person {
constructor(name, age, grade) {
super(name, age)
this.grade = grade;
}
// 子类、父类具有同名方法时,子类会覆盖父类
sperak() {
console.log(`我叫${this.name}, 今年${this.age}岁,上${this.grade}年级`)
}
}
let p1 = new Person("张三", 18)
let s1 = new Student("李四", 16, "高一")
console.log(p1)
console.log(s1)
p1.sperak() //我叫张三, 今年18岁
s1.sperak() //我叫李四, 今年16岁,上高一年级
script>
ReactDOM.render( , document.getElementById("test"))
方法将类式组件渲染到页面
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
// 1、创建类式组件
class MyComponent extends React.Component {
render() {
// render 是放在哪里的? --- MyComponent 的原型对象上,供实例使用
// render 中的 this 是谁? --- MyComponent 的实例对象 《===》 MyComponent组件实例对象
return <h1>使用类定义的组件(适用于复杂组件的定义)</h1>
}
}
// 2、渲染组件到页面上
ReactDOM.render(<MyComponent />, document.getElementById("test"))
/*
执行 ReactDOM.render( , document.getElementById("test")) 后,发生了什么?
1、React 解析组件标签,找到 MyComponent 组件
2、发现组件是使用类定义的,随后 new 出来该类的实例,并通过该实例调用到原型上的 render 方法
3、将 render 返回到虚拟DOM转化为真实DOM,随后呈现在页面中
*/
script>
body>
this.changeWeather = this.change.bind(this)
this.setState({isHot: !isHot})
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Weather extends React.Component {
// 构造器调用几次?---1次(页面初始化时调用1次)
constructor(props) {
super(props)
this.state = {
isHot: true,
wind: "大风"
}
// 解决 chengWeather 中 this 指向问题
// 这里也可以用 this.change = this.change.bind(this),render方法中用 onClick={this.change}
// 说明:上面赋值语句右边的 change 方法是挂到 Weather 的原型对象上的,等号左边的 change 是挂到 实例对象上的,
// 点击的时候,其实是实例对象调用change,因为实例对象上有 change ,所以会执行 实例对象上的change而不是原型对象上的change
this.changeWeather = this.change.bind(this)
}
// render 调用几次?---1+n次,1是初始化那次,n 是状态更新的次数
render() {
let { isHot, wind } = this.state
// return 今天天气很{ this.state.isHot ? '炎热':'凉爽' }
return <h1 id="title" onClick={this.changeWeather}>今天天气很{ isHot ? '炎热':'凉爽' }, { wind }</h1>
}
// change 调用几次?---id="title" 元素点击几次就调用几次
change() {
// change 放在哪里? --- Weather 的原型对象上,供实例使用
// 今天天气很{ this.state.isHot ? '炎热':'凉爽' }
// 上一行中 由于 change 是作为 onClick 的回调,所以 change 不是通过实例调用的,是直接调用,
// 又由于类中的方法默认开启了局部的严格模式,所以 change 中的 this 为 undefined。
// 要解决这个问题,需要在构造函数中,通过 bind 重新指定 this ==》this.changeWeather = this.change.bind(this)
// 意思是,将 change 中的 this 指向实例对象,并将这个方法赋值给 实例对象的 changeWeather 属性上面
// 最后在 render 方法中为节点绑定事件时,使用 changeWeather ,这样在点击节点时,changeWeather 里面拿到的 this 就是实例对象
// console.log(this)
let { isHot } = this.state;
// !!!注意:状态必须通过 setState 进行更新,页面才会更新,且这里是合并(不影响其他键值对),不是直接替换 state 对象
this.setState({isHot: !isHot})
// !!!注意:状态(state)不能直接(赋值)更改,直接更改,页面不会更新,下面这行代码就是直接更改,数据会被修改,但是页面不会重新渲染
// this.state.isHot = !this.state.isHot;
// console.log(this.state.isHot)
}
}
ReactDOM.render(<Weather/>, document.getElementById("test"))
// 1、绑定事件:addEventListener
// document.getElementById("title").addEventListener("click", () => {
// alert("123")
// })
// 2、绑定事件:onclick
// document.getElementById("title").onclick = () => {
// alert("456")
// }
// 3、绑定事件:行内 onClick
// 注:元素上必须要用小驼峰 onClick,而不能用 onclick,值为函数,所以要用 {demo}
// 方法加括号的话,意思是将 demo 函数调用的返回值,赋值给onClick 作为回调,
// 也就是会在初始化时执行1次,后续点击无效,所以这里不能加括号
// 这里区别于 vue,vue 中,加括号表示要传值
// function change () {
// alert("789")
// }
script>
body>
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Weather extends React.Component {
// 初始化状态
state = { isHot: false, wind: "大风" }
render() {
let { isHot, wind } = this.state;
return <h1 onClick={this.changeWeather}>今天天气很{isHot?'炎热':'凉爽'}, {wind}</h1>
}
// 自定义方法,放到实例上的 -- 要用赋值语句 + 剪头函数的形式
changeWeather = () => {
// 剪头函数里的this指向定义函数时的this
let { isHot } = this.state;
this.setState({isHot: !isHot})
}
}
ReactDOM.render(<Weather />, document.getElementById("test"))
script>
body>
作用:
{...obj}
,react 内部会将对象中的键值对展开,以 key=value
的形式当到标签上<body>
<div id="test1">div>
<div id="test2">div>
<div id="test3">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Person extends React.Component {
render() {
console.log(this) // Person 的实例对象
let { name, age, sex } = this.props;
return (
<ul>
<li>姓名:{ name }</li>
<li>性别:{ sex }</li>
<li>年龄:{ age }</li>
</ul>
)
}
}
ReactDOM.render(<Person name="张三" sex="女" age="18"/>, document.getElementById("test1"))
let p = { name: "李四", sex: "女", age: "18" }
ReactDOM.render(<Person name={p.name} sex={p.sex} age={p.sex}/>, document.getElementById("test2"))
// 这里的 { ...p } 是由 jsx 和 react 处理的,会将对象 p 里的键值对拆开分别以键值对的形式放到标签上面,
// 是上面一行代码的语法糖
ReactDOM.render(<Person { ...p }/>, document.getElementById("test2"))
ReactDOM.render(<Person name="王五" sex="女" age="18"/>, document.getElementById("test3"))
script>
body>
有两种写法,可以使用 Person.xxx
方式,也可以在类里面使用 static
关键字实现。
// 法一:
// 对标签属性进行类型、必要性的限制
// PropTypes 是文件 prop-types.js 提供的
Person.propTypes = {
name: PropTypes.string.isRequired
}
// 指定默认标签属性值
Person.defaultProps = {
sex: "未知",
}
// 法二:
class Person extends React.Component {
static propTypes = {}
static defaultProps = {}
}
Person.propTypes
对标签属性进行类型、必要性的限制
Person.defaultProps
指定默认标签属性值<body>
<div id="test1">div>
<div id="test2">div>
<div id="test3">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script src="../js/prop-types.js">script>
<script type="text/babel">
class Person extends React.Component {
// 对标签属性进行类型、必要性的限制
// PropTypes 是文件 prop-types.js 提供的
// static 标记为静态属性,只能通过类去访问,不能通过实例对象访问
static propTypes = {
name: PropTypes.string.isRequired, // 限制name为必传,且类型为字符串
sex: PropTypes.string, //限制sex为字符串
age: PropTypes.number, //限制age为数值
speak: PropTypes.func
}
// 指定默认标签属性值
static defaultProps = {
sex: "未知", // sex 默认值为 未知
age: 0 // age 默认值为 0
}
render() {
let { name, sex, age } = this.props;
return (
<ul>
<li>姓名:{ name }</li>
<li>性别:{ sex }</li>
<li>年龄:{ age }</li>
</ul>
)
}
}
// 对标签属性进行类型、必要性的限制
// PropTypes 是文件 prop-types.js 提供的
// 这里 propTypes、defaultProps 是静态属性,只能通过类去访问,无法通过实例访问,也可以在定义类的时候通过 static 增加类的静态属性
// Person.propTypes = {
// name: PropTypes.string.isRequired, // 限制name为必传,且类型为字符串
// sex: PropTypes.string, //限制sex为字符串
// age: PropTypes.number, //限制age为数值
// speak: PropTypes.func
// }
// // 指定默认标签属性值
// Person.defaultProps = {
// sex: "未知", // sex 默认值为 未知
// age: 0 // age 默认值为 0
// }
ReactDOM.render(<Person name="张三" sex="男" age={18}/>, document.getElementById("test1"))
let p = { name: "李四" }
ReactDOM.render(<Person {...p} speak={speak}/>, document.getElementById("test2"))
function speak () {
console.log("123")
}
script>
body>
class Person extends React.Component {
// 构造器是否接受 props,是否传递给 super,取决于:是否希望在构造器中通过 this 访问 props
constructor(props) {
super(props)
console.log(this.props)
}
}
注:三大属性state、props、refs中,只有props可以使用在函数式组件中,其他两个只能在类式组件中使用。
<body>
<div id="test1">div>
<div id="test2">div>
<div id="test3">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script src="../js/prop-types.js">script>
<script type="text/babel">
// 函数式组件中,函数接受一个参数,这个参数是组件标签里的属性键值对组成的对象
function Person (props) {
let { name, age, sex } = props;
return (
<ul>
<li>姓名:{ name }</li>
<li>性别:{ sex }</li>
<li>年龄:{ age }</li>
</ul>
)
}
// 对标签属性进行类型、必要性的限制
// PropTypes 是文件 prop-types.js 提供的
// 这里 propTypes、defaultProps 是静态属性,只能通过类去访问,无法通过实例访问,也可以在定义类的时候通过 static 增加类的静态属性
Person.propTypes = {
name: PropTypes.string.isRequired, // 限制name为必传,且类型为字符串
sex: PropTypes.string, //限制sex为字符串
age: PropTypes.number, //限制age为数值
speak: PropTypes.func
}
// 指定默认标签属性值
Person.defaultProps = {
sex: "未知", // sex 默认值为 未知
age: 0 // age 默认值为 0
}
ReactDOM.render(<Person name="张三" sex="男" age={18}/>, document.getElementById("test1"))
let p = { name: "李四" }
ReactDOM.render(<Person {...p} />, document.getElementById("test2"))
script>
body>
ref="XXX"属性
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Demo extends React.Component {
showData = () => {
alert(this.refs.input1.value)
}
showData2 = () => {
alert(this.refs.input2.value)
}
render() {
return (
<div>
<input ref="input1" type="text" placeholder="点击按钮弹出输入框内容"/>
<button onClick={this.showData}>点击按钮弹出左侧内容</button>
<input onBlur={this.showData2} ref="input2" type="text" placeholder="失去焦点弹出输入框内容" />
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
script>
body>
ref={ (currentNode) => { this.XXX = currentNode }}
将节点 currentNode(当前节点) 放到实例对象的 XXX 上面。(页面初始化的时候 react 会调用一次 ref 的回调,回调里面有参数,是当前节点。)<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Demo extends React.Component {
showData = () => {
alert(this.input1.value)
}
showData2 = () => {
alert(this.input2.value)
}
// 回调式 ref 有两种写法:
// 1、直接定义一个方法
// 2、内联方式写到 html 上(该方法,在更新过程中,会被调用两次,但对功能没有影响)
saveInput1 = (currentNode) => {
this.input1 = currentNode
}
render() {
return (
<div>
{/* this.input1 = currentNode} type="text" placeholder="点击按钮弹出输入框内容"/>*/}
<input ref={this.saveInput1} type="text" placeholder="点击按钮弹出输入框内容"/>
<button onClick={this.showData}>点击按钮弹出左侧内容</button>
<input onBlur={this.showData2} ref={currentNode => this.input2 = currentNode} type="text" placeholder="失去焦点弹出输入框内容" />
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
script>
body>
注意:内联回调的调用次数问题
如果ref
回调函数是一内联函数的方式定义的,在 更新 过程中它会被执行两次,第一次传入参数null
,第二次传入参数 DOM 元素。这是因为在每次渲染时,会创建一个新的函数实例,所以 React 清空旧的 ref 并设置新的。大多数情况下它是无关紧要的。
如果不想要在更新过程中被调用两次,可以使用方法1,另外定义一个方法。
React.createRef
调用后,可以返回一个容器,该容器可以存储被 ref 标识的节点,该容器时 “专人专用”的。<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Demo extends React.Component {
input1Ref = React.createRef();
input2Ref = React.createRef();
showData = () => {
alert(this.input1Ref.current.value)
}
showData2 = () => {
alert(this.input2Ref.current.value)
}
render() {
return (
<div>
<input ref={this.input1Ref} type="text" placeholder="点击按钮弹出输入框内容"/>
<button onClick={this.showData}>点击按钮弹出左侧内容</button>
<input onBlur={this.showData2} ref={this.input2Ref} type="text" placeholder="失去焦点弹出输入框内容" />
</div>
)
}
}
ReactDOM.render(<Demo/>, document.getElementById("test"))
script>
body>
onXxx
属性指定事件处理函数(注意大小写)
不绑定变量,随用随取的组件,如:输入框、下拉框等
案例:
实现登录表单:显示用户名、密码,点击登录,弹出用户名、密码,不跳转页面。
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Login extends React.Component {
confirm = (event) => {
// 阻止默认事件(此处禁止表单提交后跳转页面)
event.preventDefault();
let { usernameEl, passwordEl } = this;
alert(`你输入的用户名是${usernameEl.value},密码是${passwordEl.value}`)
}
render() {
return (
<form action="http://www.baidu.com" onSubmit={this.confirm}>
用户名:<input ref={el => this.usernameEl = el} type="text" name="username" />
密码:<input ref={el => this.passwordEl = el} type="password" name="password" />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById("test"))
script>
body>
根据用户输入,维护状态的组件是受控组件。
案例:
实现登录表单:显示用户名、密码,点击登录,弹出用户名、密码,不跳转页面。
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Login extends React.Component {
// 初始化数据
state = {
username: "",
password: ""
}
// 输入框内容更改,调用以下方法
saveUsername = (event) => {
this.setState({ username: event.target.value })
}
savePassword = (event) => {
this.setState({ password: event.target.value })
}
confirm = (event) => {
// 阻止默认事件(此处禁止表单提交后跳转页面)
event.preventDefault();
console.log(this)
let { username, password } = this.state;
alert(`你输入的用户名是${username},密码是${password}`)
}
render() {
return (
<form action="http://www.baidu.com" onSubmit={this.confirm}>
用户名:<input onChange={this.saveUsername} type="text" name="username" />
密码:<input onChange={this.savePassword} type="password" name="password" />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById("test"))
script>
body>
见另一条笔记
八、react中的事件处理 - >2、受控组件
中的案例可以利用高阶函数实现:
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Login extends React.Component {
state = {
username: "",
password: ""
}
// 符合高阶函数第2条的定义,所以 saveFormData 函数叫做高阶函数
// 符合函数柯里化的定义,所以 saveFormData 函数也叫函数的柯里化
saveFormData = (dateType) => {
return (event) => {
this.setState({ [dateType]: event.target.value })
}
}
confitm = (event) => {
event.preventDefault();
const { username, password } = this.state;
alert(`你输入的用户名是${username},密码是${password}`)
}
render() {
return (
<div>
<form action="" onSubmit={this.confitm}>
用户名:<input onChange={this.saveFormData("username")} type="text" name="user"/>
密码:<input onChange={this.saveFormData("password")} type="password" name="password" />
<button>登录</button>
</form>
</div>
)
}
}
ReactDOM.render(<Login/>, document.getElementById("test"))
script>
body>
组件标签中使用剪头函数,剪头函数中使用实例对象的方法,将需要的参数传出去。
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Login extends React.Component {
state = {
username: "",
password: ""
}
saveFormData = (dateType, event ) => {
this.setState({ [dateType]: event.target.value })
}
confitm = (event) => {
event.preventDefault();
const { username, password } = this.state;
alert(`你输入的用户名是${username},密码是${password}`)
}
render() {
return (
<div>
<form action="" onSubmit={this.confitm}>
用户名:<input onChange={event => this.saveFormData("username", event)} type="text" name="user"/>
密码:<input onChange={event => this.saveFormData("password", event)} type="password" name="password" />
<button>登录</button>
</form>
</div>
)
}
}
ReactDOM.render(<Login/>, document.getElementById("test"))
script>
body>
ReactDOM.render()
触发------初次渲染
this.setState()
或者父组件 render
触发
ReactCOM.unmountComponentAtNode()
触发
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script type="text/babel">
class Count extends React.Component {
// 初始化
constructor(props) {
super(props)
this.state = {
count: 0
}
console.log("Count---constructor")
}
add = () => {
let { count } = this.state;
this.setState({count: count+=1})
}
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById("test"))
}
force = () => {
this.forceUpdate()
}
// 组件将要挂载的钩子
componentWillMount() {
console.log("Count---componentWillMount")
}
// 组件挂载完毕的钩子
componentDidMount() {
console.log("Count---componentDidMount")
}
// 组件是否要更新的钩子
// 不写该钩子,默认返回 true,要更新
// 返回false,则不更新
// 控制组件更新的阀门
shouldComponentUpdate() {
console.log("Count---shouldComponentUpdate")
return true;
}
// 组件将要更新的钩子
componentWillUpdate() {
console.log("Count---componentWillUpdate")
}
// 组件更新完毕的钩子
componentDidUpdate() {
console.log("Count---componentDidUpdate")
}
// 组件将要卸载掉狗子
componentWillUnmount() {
console.log("Count---componentWillUnmount")
}
render() {
console.log("Count---render")
return (
<div>
<h1>当前求和为{this.state.count}</h1>
<button onClick={this.add}>点击+1</button>
<button onClick={this.death}>卸载组件</button>
<button onClick={this.force}>强制更新组件</button>
</div>
)
}
}
// ReactDOM.render( , document.getElementById("test"))
class A extends React.Component {
state = {
carname: "奔驰"
}
changeCar = () => {
this.setState({ carname: "宝马" })
}
render() {
return (
<div>
<h1>这是A组件</h1>
<button onClick={this.changeCar}>点击切换A组件的信息</button>
<B carname={this.state.carname} />
</div>
)
}
}
class B extends React.Component {
// 组件将要接收新的 props 钩子
componentWillReceiveProps() {
console.log("B---componentWillReciveProps")
}
// 控制组件更新的阀门
shouldComponentUpdate() {
console.log("B---shouldComponentUpdate")
return true;
}
// 组件将要更新的钩子
componentWillUpdate() {
console.log("B---componentWillUpdate")
}
// 组件更新完毕的钩子
componentDidUpdate() {
console.log("B---componentDidUpdate")
}
render() {
console.log("B---render")
return (
<div>
<h1>这是B组件,接收到A组件的信息是{this.props.carname}</h1>
</div>
)
}
}
ReactDOM.render(<A/>, document.getElementById("test"))
script>
body>
UNSAFE_
,最新版本已经移除。