React快速暴力入门(二)

本文是React快速暴力入门的第二部分,详细讲解了React组件的props、refs的使用,包括不同形式的refs绑定以及在类式和函数式组件中的应用。此外,还介绍了事件绑定的方法以及React的事件处理机制。最后,概述了React组件的生命周期,对比了React 16前后生命周期的变化,强调了关键的生命周期函数及其注意事项。

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

React快速暴力入门(二)

1.组件的三大属性

组件的实质就是个对象,而对象自然有属性,在组件里最常用的三个属性分别是 state、props和 refs(上期呢我们已经讲过state了 有需要的可以去上一个博客看哦)
1. props
与 state不同,state是组件自身的状态(数据),而 props则是外部传入给自己的状态(数据)
props在组件内修改,必须由谁传入的即由谁修改
类式组件中使用

class Person extends React.component{

    constructor(props){     // 还记得构造函数的参数吗,也能够获取 props
        super(props);
    }

    // 可以使用静态属性 propTyps 来限制props
    static propTypes = {
         // 在 16版本前,通过使用React自带的PropTypess属性传递值
        // name: React.PropTypes.string.isRequired,
        
        // 16版本后,PropTypes被单独移出 React作为单独的个体,需要另外导入
        name: PropTypes.string.isRequired, // 字符串类型,且必须传值
        sex: PropTypes.string,  // 字符串类型
        age: PropTypes.number,  // 数字类型
        speak: PropTypes.func,  // 函数类型
    }
    
    // 可以使用静态属性 defaultProps 来设置某些 prop 的默认值
    static defaultProps = {
        sex: "男",   // 设置 sex 的 prop 默认值为 “男”
    }

    render(){
        const {name, sex, age} = this.props;    // 从 props中获取值
        return (
            <ul>
                <li>姓名:{name}}</li>
                <li>性别:{sex}</li>
                <li>年龄:{age}</li>
            </ul>
        )
    }
}

// ReactDOM.render( <Person name="Tom" sex="" age="16"/>, document.querySelector("#root"));    // 以类似属性的方式传递 props值

ReactDOM.render(<Person {...p} />, document.querySelector("#root"));  
// 可以用扩展运算符来传递 props值

在使用的时候可以通过 this.props来获取值 类式组件的 props:

  1. 通过在组件标签上传递值,在组件中就可以获取到所传递的值
  2. 在构造函数的参数里可以获取到 props
  3. 可以分别设置 propTypes 和 defaultProps 两个属性来分别操作 props的规范和默认值,两者都是直接添加在类式组件的原型对象上的(所以需要添加 static)

函数式组件中使用
还记得说函数式组件的参数是什么吗?便是 props。
传入的方式与类式组件相同,都是在组件标签中传递值

function Person(props){   // 参数为 props
    const {name, sex, age} = props;     // 使用占位符获取 props的值
    return (
        <ul>
            <li>姓名:{name}}</li>
            <li>性别:{sex}</li>
            <li>年龄:{age}</li>
        </ul>
    )
}

Person.defaultProps = {     // 设置 props默认值
    sex: "男",
    age: 18,
}
Person.propTypes = {    // 设置 props限制
    name: PropTypes.string.isRequired,
    sex: PropTypes.string,
    age: PropTypes.number,
}

const p = {name:"Jerry", sex:"女", age:16}
ReactDOM.render(<Person {...p}/>,document.querySelector("#app"));

函数组件的 props定义:

  1. 同样也是在组件标签中传递 props的值
  2. 组件函数的参数为 props
  3. 对 props的限制和设置默认值也同样实在原型对象上

2. refs
假设在你的组件里有着表单元素,然后你需要获取到其中的值,该怎么获取呢?有的人可能想给元素绑定 id后用 document.querySelector来查找元素,但这样就违背了 React的想法,又开始操作起了DOM元素,所有React提供了第三种特性 refs
在React的历史中,共有三种操作refs的方法,分别为:

  • 字符串形式
  • 回调形式
  • createRef形式

让我们一一来了解一下:
类式组件中使用 refs
1)字符串形式的 refs

class Demo extends React.Component{
    
    showData(){
         // 通过自己设定的 refs名称获取对应的元素
        const {myInput} = this.refs;   // 返回该元素
        alert(myInput.value)
    }
    
    render(){
        return (
            <div>
                { /* 通过 ref属性绑定这个 input标签 */ }
                <input type="text" ref="myInput" placeholder="search something" />
                {/* 事件绑定会在下面讲 */}
                <button onClick={this.showData}>Show Data</button>
            </div>
        )
    }
}

2). 回调形式的 refs
其实很简单,但在后来的版本中,官方觉得这样class Demo extends 做有问题,于是推出了全新的版本:使用回调函数来操作 refs

React.Component{
    
    showData(){
        const {myInput} = this;   // 返回该元素
        alert(myInput.value)
    }
    render(){
        return (
            <div>
                {/* 回调函数的参数为该元素本身,通过函数绑定在 this上 */}
                <input type="text" ref={ e => this.myInput = e } placeholder="search something" />
                <button onClick={this.showData}>Show Data</button>
            </div>
        )
    }
}

3). createRef形式(推荐)
后来的React发现,使用回调函数的形式还是会出现一些不可言喻的问题,所以,又一次推出了全新的的方法来使用 refs,便是使用 React身上的方法 createRef()

class Demo extends React.Component{

    // 使用 React.createRef() 创建一个 ref容器
    myRef = React.createRef();

    showData = ()=>{
        // 在容器中获取 DOM元素
        const {current} = this.myRef;
        alter(current.value);
    }

    render(){
        return (
            <div>
                {/* 将DOM元素绑定在容器中 */}
                <input ref={this.myRef} placeholder="点击提示数据" type="text"/>
                <button onClick={this.showData}>ShowData</button>    
            </div>
        )
    }
}

注意:一个 ref容器,只能存储一个元素(专人专用),后加入的会把前一个顶出去
函数式组件中使用 refs

  • 在React16.8前,与 state相同,函数式组件也无法使用 refs特性
  • 在React16.8后,出现了 Hook函数,使得函数式组件也有了使用 refs特性的能力

以下代码现阶段无需看懂先,了解即可。

function Demo() {
    const [count, setCount] = React.useState(0);
    function add(){
        setCount(count=> count+1);
    }
    return (
        <div>
            <h2>当前求和:{count}</h2>
            <button onClick={add}>点击加一</button>
        </div>
    )
}

2.组件的事件绑定

1. 在函数式组件中进行事件绑定
可以在函数中定义另外一个函数(内置函数)然后进行调用即可

function Demo(props){
    function showData(){
        console.log(props);
        alert("触发了事件");
    }
    return (
        <div>
            <button onClick={showData}>点击触发</button>
        </div>
    )
}

2. 在类式组件中进行事件绑定
在类式组件中可以通过类本身的方法来调用

class Demo extends React.Component{
    state = { count: 0 }    // 定义 state
    showData(){
        alert("触发了事件")
        console.log(this.state.count);; 报错
    }
    render(){
        return (
            <div>
                <button onClick={this.showData}></button>
            </div>
        )
        // 成功弹出弹窗,但是输出报错
    }
}

这里你会发现,虽然成功 alter,但是输出 state会报错,这是为什么呢?
平时在组件内使用 this.state的时候,此时 this的指向都是作用于类的原型对象,即类本身。
而在函数中,因为使用了 babel.js的缘故,js默认开启了严格模式,所以函数体的 this为 undefined,自然找不到在原型对象上的 state。
此时有两种解决方法:

  • 使用 bind、apply等方法改变 this指向
  • 使用箭头函数,改变 this指向(推荐)
class Demo extends React.Component{
    constractor(props){
        super(props);
        // this.showData = this.showData.bind(this);   // 方法1
    }
    
    state = { count: 0 }    // 定义 state
    showData = ()=>{    // 方法2
        alert("触发了事件")
        console.log(this.state.count);; 报错
    }
    render(){
        return (
            <div>
                <button onClick={this.showData}></button>
            </div>
        )
        // 成功弹出弹窗,但是输出报错
    }
}

3.React的事件处理方法
通过 onXxx属性指定事件处理函数(注意大小写
React使用的是自定义(合成)事件,而不是原生的 DOM事件(为了更好的兼容性)
React的事件是通过事件委托方式处理的(委托给组件最外层的元素)(为了更加的高效)
可以通过事件的 event.target获取发生的DOM元素对象,可以尽量减少 refs的使用
在绑定事件的时候不要加括号,这会被 jsx识别为执行函数
在类式组件中绑定函数注意 this的指向问题(推荐绑定的函数都使用箭头函数)

3.组件的生命周期

对 Vue熟悉的应该对生命周期并不陌生。
组件在挂载到页面上的过程中,期间发生了许多的事情,而生命周期,可以看作是一个组件的执行流程,我们可以通过在某个流程节点中进行一些操作,而这就是 生命周期钩子(函数)
注:生命周期函数只适用于类式组件,并不适用于函数式组件,但是在React16.8之后的 Hook,也可以让函数式组件实现类似于生命周期钩子的功能
1.React 16之前
在这里插入图片描述
以下是流程:
自身组件挂载

  1. constructor: 构造函数(初始化)
  2. componentWillMount: 组件挂载前
  3. render: 组件挂载中
  4. componentDidMount: 组件挂载完成后

拥有父组件且父组件状态进行更新(setState):

  1. 父组件 shouldComponentUpdate: 父组件是否进行状态更新
  2. 父组件 componentWillUpdate: 父组件状态更新前
  3. 父组件 render: 父组件更新挂载中
  4. 子组件 componentWillReceiveProps: 子组件将收到新的Props
  5. 子组件 shouldComponentUpdate: 子组件是否进行状态更新
  6. 子组件 componentWillUpdate: 子组件状态更新前
  7. 子组件 render: 子组件更新挂载中
  8. 子组件 componentDidMount: 子组件挂载完成
  9. 父组件 componentDidMount: 父组件挂载完成

当组件要进行卸载时:

  1. componentWillUnmount: 组件卸载前

有几个需要注意的地方:

  • shouldComponentUpdate的意思是是否更新状态,所以他应该有个布尔类型返回值,而且默认为 true(不写的时候),当你写了这个钩子时别忘了写个返回值,这个横眉周期一般用于进行更新值的一些判断。
  • shouldComponentUpdate有两个参数,分别是 nextProps:新的props 与 nextState: 新的state,此时他们都还没更新到组件上。
  • 使用 setState时会经过生命周期 shouldComponentUpdate,但是使用 forceUpdate时则不会,而是直接到 componentWillUpdate生命周期

2. React 16之后
在这里插入图片描述
新旧生命周期对比:
1.在新的生命周期中,舍弃了(即将舍弃)三个生命周期函数:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

2.新增了两个生命周期函数:

  • getDerivedStateFromProps
  • getSnapshotBeforeUpdate

以下是流程:

  • 自身组件挂载:
  1. constructor: 构造函数(初始化)
  2. getDerivedStateFromProps: 从props中获取派生的state
  3. render: 组件挂载中
  4. componentDidMount: 组件完成挂载

父组件更新时

  1. 父组件 getDerivedStateFromProps: 从 props中获取派生的state
  2. 父组件 shouldComponentUpdate: 判断是否进行状态更新
  3. 父组件 render: 父组件挂载中
  4. 子组件 getDerivedStateFromProps: 从 props中获取派生的state
  5. 子组件 shouldComponentUpdate: 判断是否进行状态更新
  6. 子组件 render: 子组件挂载中
  7. 子组件 getSnapshotBeforeUpdate: 子组件获取状态更新前的快照
  8. 子组件 componentDidUpdate: 子组件完成更新
  9. 父组件 getSnapshotBeforeUpdate: 父组件获取状态更新前的快照
  10. 父组件 componentDidUpdate: 父组件完成更新

组件卸载时

  1. componentWillUnmount: 组件卸载前

也有几个需要注意的地方:

  • getDerivedStateFromProps 需要定义个实例本身,所以是静态方法
  • getDerivedStateFromProps 有两个参数,分别是当前的 props和 state
  • 若需要组件的状态任何时候都取决于 props则可以使用 则可以使用 getDerivedStateFromProps,但是使用场景比较罕见,可以在其中定义 state
  • getSnapshotBeforeUpdate 有两个参数,分别为状态更新前的 props 和state,并且有一个返回值(快照),一般用作本次更新情况的说明情况。
  • componentDidUpdate 有三个参数,分别为状态更新前的 props 和 state,以及先前 getSnapshotBeforeUpdate返回的快照。
  • 其他的与旧的生命周期没有什么差别

4.总结

相信你也看完了整个了,我们今天讲了属性 生命周期 事件绑定等等 哪在本文中呢 我也在该注意的地方写了要注意什么 如果本文还有什么有不懂的 也可以看官网哦

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值