React(二)

本文详细介绍了React中的组件生命周期方法,包括挂载阶段的componentWillMount和componentDidMount,更新阶段的shouldComponentUpdate、componentWillUpdate及componentDidUpdate,卸载阶段的componentWillUnmount等,并演示了如何利用这些方法进行状态管理和组件间的通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

生命周期函数

在这里插入图片描述

componentWillMount

在组件渲染之前执行

componentDidMount

在组件渲染之后执行

shouldComponentUpdate

返回true/false,true代表允许改变,false代表不允许改变

componentWillUpdate

数据在改变之前执行(state,props)

componentDidUpdate

数据修改完成(state,props)

componentWillReceiveProps

props发生改变执行

componentWillUnmount

组件卸载前执行

app.jsx

// 引入react库
import  React from "react"

//引入组件
import Home from "./home"

import MyNav from "./MyNav"

import StateComponent from "./StateComponent"

import ComponentLife from "./ComponentLife"

// 用类的形式创建组件
class App extends React.Component{
    constructor(){
        super();
        this.state ={
            title:"文本1"
        }
    }

    clickChange =()=>{
        this.setState({
            title:"文本2"
        })
    }
    // 渲染函数
    render(){
        const nav1 = ["首页","视频","学习"];
        const nav2 = ["WEB","JAVA","PHP"];

        return(
            <div>
              {/* <h1>Hello React Component</h1>
              <h3>学习react</h3>
              <Home />
              <MyNav nav={ nav1 } title="路径导航"/>
              <MyNav nav={ nav2 } title="学习导航"/> */}
              {/* <StateComponent /> */}
              <ComponentLife title={ this.state.title}/>
              <button onClick={ this.clickChange }>修改title</button>
            </div>
        )
    }
} 

// 导出组件
export default App
ComponentLife.jsx

import React from "react"
 
export default class ComponentLife extends React.Component{
    
    constructor(props){
        super(props);
        this.state ={
            count:10
        }
    }
    componentWillMount (){
        console.log("componentWillMount");
    }
    componentDidMount (){
        console.log("componentDidMount");
    }
    shouldComponentUpdate (){
        console.log("shouldComponentUpdate");
        return true ;
    }
    componentWillUpdate (){
        console.log("ComponentWillUpdate");
    }
    componentDidUpdate (){
        console.log("ComponentDidUpdate");
    }
    componentWillReceiveProps (){
        console.log("ComponentWillReceiveProps");
    }
    componentWillUnmount (){
        console.log("ComponentWillUnmount");
    }
    changeHandler =()=>{
        this.setState({
            count:this.state.count+=1
        })
    }
    render(){
        const { count } =this.state;
        return(
            <div>
                生命周期函数:{ count } -{ this.props.title }
                <button onClick={ this.changeHandler }>修改</button>
            </div>
        )
    }

}

在这里插入图片描述

当props发生改变时,执行了componentWillReceiveProps

在这里插入图片描述

子传父

可以通过props向父组件传值

app.jsx 这是父组件

// 引入react库
import  React from "react"

//引入组件
import Home from "./home"

import MyNav from "./MyNav"

import StateComponent from "./StateComponent"

import ComponentLife from "./ComponentLife"

// 用类的形式创建组件
class App extends React.Component{
    constructor(){
        super();
        this.state ={
            title:"文本1"
        }
    }

    clickChange =(data)=>{
        this.setState({
            title:data
        })
    }
    // 渲染函数
    render(){
        const nav1 = ["首页","视频","学习"];
        const nav2 = ["WEB","JAVA","PHP"];

        return(
            <div> 
              {/* <h1>Hello React Component</h1>
              <h3>学习react</h3>
              <Home />
              <MyNav nav={ nav1 } title="路径导航"/>
              <MyNav nav={ nav2 } title="学习导航"/> */}
              {/* <StateComponent /> */}
              < ComponentLife title={ this.state.title} clickChanges={ this.clickChange }/>
              
            </div>
        )
    }
} 

// 导出组件
export default App
ComponentLife.jsx 这是子组件

import React from "react"
 
export default class ComponentLife extends React.Component{
    
    constructor(props){
        super(props);
        this.state ={
            count:10
        }
    }
    componentWillMount (){
        console.log("componentWillMount");
    }
    componentDidMount (){
        console.log("componentDidMount");
    }
    shouldComponentUpdate (){
        console.log("shouldComponentUpdate");
        return true ;
    }
    componentWillUpdate (){
        console.log("ComponentWillUpdate");
    }
    componentDidUpdate (){
        console.log("ComponentDidUpdate");
    }
    componentWillReceiveProps (){
        console.log("ComponentWillReceiveProps");
    }
    componentWillUnmount (){
        console.log("ComponentWillUnmount");
    }
    changeHandler =()=>{
        this.setState({
            count:this.state.count+=1
        })
    }
    clickChange =()=>{
        this.props.clickChanges('我是儿子的数据');
    }
    render(){
        const { count } =this.state;
        return(
            <div>
                生命周期函数:{ count } -{ this.props.title }
                <button onClick={ this.changeHandler }>修改</button>
                <button onClick={ this.clickChange }>修改title</button>
            </div>
        )
    }

}

<button onClick={ this.clickChange }>修改title</button>这段代码原来是父组件中的,如果写在子组件中,通过props定义一个clickChanges传到父组件中

子组件定义的props

clickChange =()=>{
        this.props.clickChanges('我是儿子的数据');
}

父组件中< ComponentLife title={ this.state.title} clickChanges={ this.clickChange }/>

同时传送的数据可以发生改变,直接将title定义为data

clickChange =(data)=>{
        this.setState({
            title:data
        })
}

setState的更新问题

setState会引起视图的重绘

setState在可控的情况下是异步,在非可控的情况下是同步

app.jsx

// 引入react库
import  React from "react"

//引入组件
import Home from "./home"

import MyNav from "./MyNav"

import StateComponent from "./StateComponent"

import ComponentLife from "./ComponentLife"

import SetStateDemo from "./setStateDemo"

// 用类的形式创建组件
class App extends React.Component{
    constructor(){
        super();
        this.state ={
            title:"文本1"
        }
    }

    clickChange =(data)=>{
        this.setState({
            title:data
        })
    }
    // 渲染函数
    render(){
        const nav1 = ["首页","视频","学习"];
        const nav2 = ["WEB","JAVA","PHP"];

        return(
            <div> 
              {/* <h1>Hello React Component</h1>
              <h3>学习react</h3>
              <Home />
              <MyNav nav={ nav1 } title="路径导航"/>
              <MyNav nav={ nav2 } title="学习导航"/> */}
              {/* <StateComponent /> */}
              {/* < ComponentLife title={ this.state.title} clickChanges={ this.clickChange }/> */}
              <SetStateDemo />
            </div>
        )
    }
} 

// 导出组件
export default App

这是使用异步方法实现数据的更新

import React from "react"

export default class SetStateDemo extends React.Component{
    constructor(){
        super();
        this.state ={
            count:0
        }
    }
    increment =()=>{
        this.setState({
            count:this.state.count+1
        },()=>{
            console.log(this.state.count);
        })
    }
    // async increment(){
    //     await this.setStateAsync({count:this.state.count+1});
    //     console.log(this.state.count);
    // }
    // setStateAsync(state){//自己定义一个同步方法
    //     return new Promise((resolve)=>{
    //         this.setState(state,resolve);
    //     })
    // }
    render (){
        return(
            <div>
                setState同步还是异步问题
                <p> { this.state.count } </p>
                <button onClick={ this.increment.bind(this) }> 修改 </button>
            </div>
        )
    }
}

在这里插入图片描述

注释掉的代码是使用同步方法实现数据的更新,实现的效果是相同的,自己定义一个同步方法setStateAsync

async increment(){
        await this.setStateAsync({count:this.state.count+1});
        console.log(this.state.count);
    }
    setStateAsync(state){//自己定义一个同步方法
        return new Promise((resolve)=>{
            this.setState(state,resolve);
        })
    }

条件渲染

常用的应用场景有两个:一种是对视图条件进行切换,另一种是做缺省值

用户登录页面的切换就是第一种应用场景

还是在app.jsx中引入组件

import IfDemo from "./ifDemo"

并在return返回值中使用组件

<IfDemo />

ifDemo.jsx

import React from "react"

export default class IfDemo extends React.Component{
    constructor(){
        super();
        this.state={
            isLogin:false
        }
    }
    ClickHandler =() =>{
       this.setState({
           isLogin:true
       })  
    }
    render(){
        let showView =this.state.isLogin?
        <div>iven</div> :
        <div>请登录</div>
        return(
            <div>
                条件渲染:{ showView}
                <button onClick={ this.ClickHandler}>登录</button>
            </div>
        )
   }
}

在这里插入图片描述

另一种做缺省值的场景,是数据在传递时可能会出现空的情况,这时需要对数据进行判断

ifDemo.jsx

import React from "react"

export default class IfDemo extends React.Component{
    constructor(){
        super();
        this.state={
            isLogin:false,
            names:["iven","ime"]
        }
    }
    ClickHandler =() =>{
       this.setState({
           isLogin:true
       })  
    }
    render(){
        const { names } =this.state;
        let showView =this.state.isLogin?
        <div>iven</div> :
        <div>请登录</div>
        return(
            <div>
                条件渲染:{ showView}
                <button onClick={ this.ClickHandler}>登录</button>
                {
                    names.length >0?
                    <div>
                    {
                        names.map((element,index) =>{
                            return  <p key={index}>{ element}</p>
                        })
                    }
                   </div>
                    :
                    <div>请等待数据正在读取....</div>
                }
            </div>
        )
   }
}

列表渲染

明确设置key的值会对数据有什么影响:

1.key是用来帮助react识别哪些内容被更改、添加或者删除。key需要写在用数组渲染出来的元素内部,并且需要赋予其一个稳定的值。如果key值发生了变更,react则会触发UI的重渲染。
2.在相邻的元素间,key值必须是唯一的,若出现了相同的key值,会抛出警告,告诉相邻组件间有重复的key值,且只会渲染第一个重复key值中的元素,因为react会认为后续拥有相同key值的都是同一个组件。
3.虽然我们在组件上定义了key值,但是在其子组件中,我们并没有办法拿到key值,因为key值仅仅是给react内部使用的。如果我们需要使用到key值,可通过其他方式传入,比如将key值赋值给id等。

同样的还是在app.jsx中引入组件

import KeyDemo from "./KeyDemo"

并在return返回值中使用组件

<KeyDemo />

KeyDemo.jsx

import React from "react"

export default class KeyDemo extends React.Component{
    constructor(){
        super();
        this.state ={
            userinfo:[
                {
                    name:'iven',
                    age:20,
                    sex:'男',
                    jobs:['11','222','333']
                },
                {
                    name:'inco',
                    age:27,
                    sex:'男',
                    jobs:['19','999','323']
                },
                {
                    name:'ime',
                    age:24,
                    sex:'女',
                    jobs:['18','345','563']
                }
            ]
        }
    }

    clickHandler =() =>{
        this.setState({
            userinfo:this.state.userinfo.concat([{
                name:"sakura",
                age:30,
                sex:"女",
                jobs:['333','444','555']
            }])
        })
    }

    render(){
        return(
            <div>
               <ul>
                   {
                       this.state.userinfo.map((element,index) =>{
                           return( 
                               <li>
                                   <span> { element.name } </span>
                                   <span> { element.age } </span>
                                   <span> { element.sex } </span>
                                   <div>
                                       {
                                           element.jobs.map((childElement,childIndex) =>{
                                               return <span key={ childIndex}> { childElement }</span>
                                           })
                                       }
                                   </div>
                               </li>
                           )
                       })
                   }
               </ul>
               <button onClick={ this.clickHandler }>添加数据</button>
            </div>
        )
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值