1.Component lift cycle introduction
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
render(){
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
2.The key value in the Object is the same and can be abbreviated directly.
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
render(){
setInterval(() =>{
//get original status
let {opacity} = this.state
//decrease by 0.1
opacity -= 0.1
//set new transparency
this.setState({opacity: opacity})
}, 200)
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
- In js, 0.1 + 0.2 is not equal to 0.3 ,so it is written as < = 0
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
render(){
setInterval(() =>{
//get original status
let {opacity} = this.state
//decrease by 0.1
opacity -= 0.1
//In js, 0.1 + 0.2 is not equal to 0.3 ,so it is written as < = 0
if(opacity <= 0) opacity = 1
//set new transparency
this.setState({opacity: opacity})
}, 200)
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
-
Render grows exponentially. Setinterval cannot be called in render (including status update)
-
Let’us put seetInterval into an event handler
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
render(){
setInterval(() =>{
//get original status
let {opacity} = this.state
//decrease by 0.1
opacity -= 0.1
//
if(opacity <= 0) opacity = 1
//set new transparency
this.setState({opacity: opacity})
}, 200)
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
6.The event callback method is used, and the arrow function is used, so this is also a component instance object
Mount the timer ID on the component instance object
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//clear timer
clearInterval(this.timer)
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
componentDidMount(){
this.timer = setInterval(() => {
//get original status
let {opacity} = this.state
//Decrease by 0.1
opacity -= 0.1
if(opacity <= 0 ) opacity = 1
//set new transparency
this.setState({opacity})
}, 200);
}
render(){
console.log('render')
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
7.We recommend clearing times in this life cycle instead of using click events
class Life extends React.Component{
state = {opacity: 1}
death = () =>{
//uninstall components
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
componentDidMount(){
this.timer = setInterval(() => {
//get original status
let {opacity} = this.state
//Decrease by 0.1
opacity -= 0.1
if(opacity <= 0 ) opacity = 1
//set new transparency
this.setState({opacity})
}, 200);
}
componentWillUnmount() {
//clear timer
clearInterval(this.timer)
}
render(){
console.log('render')
return (
<div>
<h2 style={{opacity: this.state.opacity}}> React study</h2>
<button onClick={this.death}>del</button>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
8.It’s like a person’s life ,doing different things in different stages
9.Render is followed by componentDIdmount, the following render is always updated because the component is always updated
10.The initialization state is the same inside and outside the unloading constructor
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
}
//initialization status update
state = {count: 1}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
11.Same as above
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
12.mounting process
挂载时 父组件render
constructor componentWillReceiveProps
componentWillMount shouldComponentUpdate setState()
componentWillUpdate forceUpdate()
render render
componentDidMount componentDidUpdate
componentWillUnmount
13.Validate lifecyccle code
class Count extends React.Component{
/*
First construct, then mount,then render,and then mount
Count---constructor
Count---componentWillMount
Count---render
Count---componentDidMount
*/
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
14.Do not write,The defalult is true.
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//The calling order of components is independent of the write position
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
//Hook the component will unload
componentWillUnmount(){
console.log('Count---componentWillUnmount');
}
//Valve for control assembly update
shouldComponentUpdate(){
console.log('Count---shouldComponentUpdate');
//After opening and clicking, the page is not updated
return true
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
15.This is the process of setstate status update
setState()
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
componentWillUnmount
16.There are three flow lines
Parent component render
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
componentWillUnmount
16.Call the method of forced update
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
/*
Count --- componentWillUpdate
Count --- render
Count --- componentDidUpdate
*/
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//Force callback of update button
force = () => {
thie.forceUpdate()
}
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
//Hook the component will unload
componentWillUnmount(){
console.log('Count---componentWillUnmount');
}
//Valve for control assembly update
shouldComponentUpdate(){
console.log('Count---shouldComponentUpdate');
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
17.Calling component B from component A
class A extends React.Component{
state = {car}
render() {
return(
<div>
<div>A</div>
<B/>
</div>
)
}
}
class B extends React.Component{
render(){
return(
<div>B</div>
)
}
}
ReactDOM.render(<A/>,document.getElementById('test'))
Display on devaloper tools
A
B
18.The componentWillReceiveNewProps hook does not count the data received for the first time
19.Demonstration of parent component value transfer and hook function
class A extends React.Component{
state = {car}
render() {
return(
<div>
<div>This is component A</div>
<button onClick={this.changeCar}>changeCar</button>
<B carName={this.state.carName} />
</div>
)
}
}
class B extends React.Component{
componentWillReceiveProps(props) {
console.log('B---componentWillReceiveProp',props);
}
render(){
return(
<div>This is component B. the car I received is: {this.props.carName}</div>
)
}
}
ReactDOM.render(<A/>,document.getElementById('test'))
20.Verification process in component B
class A extends React.Component{
state = {car}
render() {
return(
<div>
<div>This is component A</div>
<button onClick={this.changeCar}>changeCar</button>
<B carName={this.state.carName} />
</div>
)
}
}
class B extends React.Component{
componentWillReceiveProps(props) {
console.log('B---componentWillReceiveProp',props);
}
//Value for control assembly update
shouldComponentUpdate(){
console.log('B---componentWillUpdate')
}
//The hook that the component will update
componentWillUpdate(){
console.log('B---componentWillUpdate');
}
//Hook after component update
componentDidUpdate() {
console.log('B---componentDidUpdate')
}
render(){
return(
<div>This is component B. the car I received is: {this.props.carName}</div>
)
}
}
ReactDOM.render(<A/>,document.getElementById('test'))
/*
B---componentWillReceiveProps {carName: '奥托'}
B---shouldComponentUpdate
B---componentWillUpdate
B---render
B---componentDidUpdate
*/
21 Life cycle function summary
/*
1.初始化阶段:由ReactDOM.render()触发---初次渲染
1.constructor()
2.componentWillMount()
3.render()
4.componentDidMount() ===> 常用
2.Update phase: Triggered by this.setState() inside the component or render of the parent component
1.shouldComponentUpdate()
2.componentWillUpdate()
3.render() =====> Must be used
4.componentDidUpdate()
3.Unloading components: triggered by ReactDOM.UnmountcomponentAtNode()
1.componentWillUnmount() ===> commonly used
Generally, we do some finishing woek in this hook,such as closing the timer and
unsubscribing messages
*/
22 react in verson 17 is paving the way to for future versions
我们得到的最重要的经验是,过程的组件生命周期往往会带来不安全的编码实践,具体函数如下:
componentWillMount
componentWillReceiveProps
componentWillUpdate
这些生命周期方法经常被误解和滥用;此外我们预计,在异步渲染中,它们潜在的误用问题可能更大,我们将在即将发布的版本中为这些生命周期添加“UNSAFE_”前缀。(这里的“unsale”不是指安全性,而是表示使用这些生命周期的代码在React的未来版本中更有可能出现bug,尤其是在启用异步渲染之后。)
23.Old and new life cycle
挂载时 父组件render
constuctor componentWillReceiveProps
componentWillMount shouldComponentUpdate
componentWillUpdate
render render
componentDidMount componentDidUpdate
componentWillUnmount
挂载时 更新时 卸载时
constructor
getDerivedStateFormProps
shouldComponentUpdate
render
getSnapshotBeforeUpdate
React 更新DOM和refs
componentDidMount componentDidUpdate componentWillUnmount
Compared with the new one, the old one cancels 3 life cycles and adds 2 life cycles that are not commonly used
24.Accept a props and return a props
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//Force callback of update button
force = () => {
this.forceUpdate()
}
//The output value is: getDerivedStateFromProps { count: "199"} { count: 0 }
static getDerivedStateFromProps(props, state){
console.log('getDerivedStateFormProps', props, state);
return props
}
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
//Hook the component will unload
componentWillUnmount(){
console.log('Count---componentWillUnmount');
}
//Valve for control assembly update
shouldComponentUpdate(){
console.log('Count---shouldComponentUpdate');
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
25.getSnapshotBeforeUpdate()
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//Force callback of update button
force = () => {
this.forceUpdate()
}
static getDerivedStateFromProps(props, state){
console.log('getDerivedStateFormProps', props, state);
return props
}
/*
Take a snapshot at the new year's party.After taking a snapshot,
it will be scattered to componentDidUpdate.Therefore,its value is
passed to the latter
*/
getSnapshotBeforeUpdate(){
console.log('getSnapshotBeforeUpdate');
return 'aaa'
}
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
//Hook the component will unload
componentWillUnmount(){
console.log('Count---componentWillUnmount');
}
//Valve for control assembly update
shouldComponentUpdate(){
console.log('Count---shouldComponentUpdate');
}
render(){
const {count} = this.state
return(
<div>
<h2>The current sum is: {count}</h2>
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
class Count extends React.Component{
// constructor
constructor(props) {
console.log('Count-constructor');
super(props)
//initialization status update
this.state = {count: 0}
}
//Callback of the plus 1 button
add = () => {
//Get original status
const {count} = this.state
//Update status
this.setState({count: count + 1})
}
//Force callback of update button
force = () => {
this.forceUpdate()
}
static getDerivedStateFromProps(props, state){
console.log('getDerivedStateFormProps', props, state);
return props
}
/*
Take a snapshot at the new year's party.After taking a snapshot,
it will be scattered to componentDidUpdate.Therefore,its value is
passed to the latter
*/
getSnapshotBeforeUpdate(){
console.log('getSnapshotBeforeUpdate');
return this.refs.list.scrollHeight
}
//distance from scroll bar to top
componentDidUpdate(preProps, preState, height){
this.refs.list.scrollTop += this.refs.list.scrollHeight - height
}
//Hook the component will mount
componentWillMount() {
console.log('Count---componentWillMount');
}
//Hook after component mounting
componentDidMount(){
console.log('Count---componentDidMount');
}
//Hook the component will unload
componentWillUnmount(){
console.log('Count---componentWillUnmount');
}
//Valve for control assembly update
shouldComponentUpdate(){
console.log('Count---shouldComponentUpdate');
}
render(){
return(
<div className="list" ref="list">
{
this.state.newArr.map((n,index) => {
return <div key={index} className="news">{n}</div>
})
}
</div>
)
}
}
// render Component
ReactDOM.render(<Life/>,document.getElementById('test'))
27。Summary of new and old hooks
- render: initialize rendering or update rendering calls
- componentDidMount: Enable listening and send Ajax requests.
- componentWillUnmount: Do some finishing work ,such as cleaning the timer.
Hook to be discarded
4. componentWillMount
5. componentWillReceiveProps
6. componentWillUpdate
There will be a warning when you use it now ,and unsafe needs to be added in the next large verson_
The prefix can only be used. It may be completely discarded in the future. It is not recommended to use it
虚拟Dom与DOM Diffing 算法
- The smallest granularity of diffing alforithm is label
class Time extends React.Component {
state = {date: new Date()}
componentDidMount () {
setInterval(() => {
this.setState({
date: new Data()
})
},1000)
}
render () {
return (
<div>
<h1>hello</h1>
<input type="text"/>
<span>
{/*diffing算法最小的粒度是标签*/}
Now: {this.state.date.toTimeString()}
<input type="text"/>
</span>
</div>
)
}
}
- Problems caused by using index as index
/*
// initial data
{id: 1, name: '小张',age: 18}
{id: 2, name: 'Mr Li', age: 19}
//initialize virtual DOM
<li key = 0>小张---18</li>
<li key = 1>小李---19</li>
//Updated data
{id: 3, name: '小王', age: 20}
{id: 1, name: '小张',age: 18}
{id: 2, name: 'Mr Li', age: 19}
//Updated virtual DOM
<li key = 0>小张---20</li>
<li key = 1>小张---18</li>
<li key = 2>小李---19</li>
*/
30.Using a unique identifier as a key is more efficient
/*
// initial data
{id: 1, name: '小张',age: 18}
{id: 2, name: 'Mr Li', age: 19}
//initialize virtual DOM
<li key = 1>小张---18</li>
<li key = 2>小李---19</li>
//Updated data
{id: 3, name: '小王', age: 20}
{id: 1, name: '小张',age: 18}
{id: 2, name: 'Mr Li', age: 19}
//Updated virtual DOM
<li key = 3>小张---20</li>
<li key = 1>小张---18</li>
<li key = 2>小李---19</li>
*/
31.The role of key in virtual DOM
Function of key in virtual M:
1). To put it simply, the key is the identifier of the virtual om object and plays an extremely important role in updating the display
2). In detail, when the data in the state changes, react will compare the diff of [new virtual om] and [old virtual O] according to [new data] [new virtual DOM], and the comparison rules are as follows:
A) the same key as the new virtual DOM was found in the old virtual do
(1) If the content in the virtual DOM does not change, directly use the previous real DOM
(2) If the content in the virtual DOM changes, a new real DOM is generated, and then the previous real DOM in the page is replaced
b. The same key as the new virtual DM was not found in the old virtual OM
Interview question: empty
Create a new real DOM according to the data, and then render it to the page
two
index
Problems caused by Ke Neng:
1. If the data is added and deleted in reverse order, it will cause unnecessary real DOM updates = the interface effect is OK, but the efficiency is low
In quasi DOM
2. If the structure also contains the dom of the input class
An error will be generated. There is a problem with the DOM update interface
Function of key
3. Attention! If there are no operations that destroy the order of data such as reverse order addition and deletion, it is only used to render the list for presentation, and there is no problem using index as the key
How to select a key in sending?
1. It is better to use the unique identifier of each piece of data as the key, such as ID, mobile phone number, ID number, student number and other unique values. 2. If it is determined that it is only a simple display of data, it is also possible to use indext
32.In the case of recerse order, using index as the unique indentifier will cause error problems