React 函数组件和类组件props、state、获取DOM用法及区别

目录

项目结构

1. React 组件创建方式

1.1 函数组件

1.1.1 在App.js中用函数创建App组件

1.1.2 在index.js 引入 App组件

1.2 类组件

1.2.1 在App.js中用类的方式创建App组件

1.2.2 在index.js 引入 App组件

1.3 区别

2. props 父传子

2.1 函数组件使用props

2.1.1 入口文件 index.js

2.1.2  父组件 ListItems.js

2.1.3 子组件 Item.js

2.2 类组件使用props 

2.2.1 入口文件 index.js

2.2.2 App.js

2.2.3  父组件 ListItems.js

2.2.4 子组件 Item.js

3. state 在React中注册变量

3.1 函数组件使用钩子 useState() 来创建state

3.2 类组件中state统一存储到了实例对象的state属性中

3.3 区别:

4. React 获取DOM对象

4.1 函数组件 从React处获取DOM对象 useRef()

4.2 类组件使用 React.createRef() 获取DOM


项目结构

1. React 组件创建方式

1.1 函数组件

  • 函数组件就是一个返回JSX的普通
  • 组件的首字母必须是大写
1.1.1 在App.js中用函数创建App组件
const App = () => {
  return <div>我是App组件!</div>
};

// 导出App
export default App;
1.1.2 在index.js 引入 App组件
import ReactDOM from "react-dom/client";
import App from "./App";


const root = ReactDOM.createRoot(document.getElementById('root'));

// React组件可以直接通过JSX渲染
root.render(<App/>);

1.2 类组件

  • 类组件必须要继承React.Component
  • 用啥变量都要用 this.xxx
1.2.1 在App.js中用类的方式创建App组件
import React from "react";
// import React,{Component} from "react";

class App extends React.Component {

    // 类组件中,必须添加一个render()方法,且方法的返回值要是一个jsx
    render() {
        return <div>我是一个类组件</div>;
    }
}

// 导出App
export default App;
1.2.2 在index.js 引入 App组件
  • 跟 1.1.2 一模一样

1.3 区别

  • 相较于函数组件,类组件的编写要麻烦一下,但是实现的功能是一样的

2. props 父传子

2.1 函数组件使用props

  • 在函数组件中,属性就相当于是函数的参数,可以通过参数来访问
  • 可以在函数组件的形参中定义一个props,props指向的是一个对象,包含了父组件中传递的所有参数
2.1.1 入口文件 index.js
// 引入ReactDOM
import ReactDOM from "react-dom/client"
import "./index.css"
import ListItems from './Components/ListItems'
// 创建一个JSX
const App = <div className="logo">
    <ListItems />
</div>

// 获取根容器
const root = ReactDOM.createRoot(document.getElementById('root'))
// 将App渲染进根容器
root.render(App)
2.1.2  父组件 ListItems.js
import Item from "./Item/Item"
const Items = () => {
    const list = [
        { id: 1, des: "打王者荣耀", time: 60, date: new Date(), },
        { id: 2, des: "学习Vue", time: 120, date: new Date(), },
        { id: 3, des: "学习React", time: 20, date: new Date() },
    ]
    return <div className="items">
        {
            list.map(item => <Item key={item.id} des={item.des} time={item.time} date={item.date}></Item>)
        }
    </div>
}
export default Items
2.1.3 子组件 Item.js
const Item = (props) => {
    console.log(props, 'props');
    return <div className="content">
        <h2 className="des">{props.des}</h2>
        <div className="time">{props.time}分钟</div>
        {/* 显示的是 中文的 五月 */}
        <div style={{ background: '#f00' }}>{props.date.toLocaleString('zh-CN', { month: 'long' })}</div>
    </div>
}
export default Item

2.2 类组件使用props 

  • 类组件的props是存储到类的实例对象中,可以直接通过实例对象访问,this.props
2.2.1 入口文件 index.js
// 引入ReactDOM
import ReactDOM from "react-dom/client"
import "./index.css"
import App from './App'

// 获取根容器
const root = ReactDOM.createRoot(document.getElementById('root'))
// 将App渲染进根容器
root.render(<App />)
2.2.2 App.js
import React from "react";
import ListItems from "./Components/ListItems"
class App extends React.Component {
    render() {
        return <ListItems></ListItems>
    }
}
export default App
2.2.3  父组件 ListItems.js

import React from "react";
import Item from "./Item/Item"
class ListItems extends React.Component {
    list = [
        { id: 1, des: "打王者荣耀", time: 60, date: new Date(), },
        { id: 2, des: "学习Vue", time: 120, date: new Date(), },
        { id: 3, des: "学习React", time: 20, date: new Date() },
    ]
    render() {
        return <div className="items">
            {
                this.list.map(item => <Item key={item.id} des={item.des} time={item.time} date={item.date}></Item>)
            }
        </div>
    }
}
export default ListItems
2.2.4 子组件 Item.js
import React from "react";
class Item extends React.Component {
    render() {
        return <div className="content">
            <h2 className="des">{this.props.des}</h2>
            <div className="time">{this.props.time}分钟</div>
            {/* 显示的是 中文的 五月 */}
            <div style={{ background: '#f00' }}>{this.props.date.toLocaleString('zh-CN', { month: 'long' })}</div>
        </div>
    }
}
export default Item

3. state 在React中注册变量

* state相当于一个变量,

  *   只是这个变量在React中进行了注册,

  *   React会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染

  *   使得我们的修改可以在页面中呈现出来

3.1 函数组件使用钩子 useState() 来创建state

  • 钩子需导入后使用:
import {useState} from "react";
  • useState() 需要一个值作为参数,这个值就是state的初始值,返回一个数组
  1. 数组中第一个元素,是初始值,初始值只用来显示数据,直接修改不会触发组件的重新渲染
  2. 数组中的第二个元素,是一个函数,通常会命名为setXxx,此函数用来修改state,调用其修改state后会触发组件的重新渲染,并且使用函数中的值作为新的state值

App.js

import { useState } from "react";

const App = () => {
    const [count, setCounter] = useState(0)
    const [other, setOther] = useState({
        age: 18,
        gender: 'w'
    })

    
    const handleCilck = () => {
        // setCounter(count + 1)

        // 会有异步的问题
        // setCounter(count + 1)

        /*
        *   setState()中回调函数的返回值将会成为新的state值
        *       回调函数执行时,React会将最新的state值作为参数传递
        * */
        setCounter(prevCount => {
            return prevCount + 1
        });

    }

    const handleCilckOther = () => {
        // other会从两个属性变成一个属性
        // setOther({ gender: 'm' })

        setOther({
            ...other, gender: 'm'
        });
    }

    return <div className="items">
        <div>{count}</div>
        <div>{other.age}</div>
        <div>{other.gender}</div>
        <button onClick={handleCilck}>点击</button>
        <button onClick={handleCilckOther}>改变other</button>
    </div>

}
export default App

注: state实际就是一个被React管理的变量

  1. 当我们通过setState()修改变量的值时,会触发组件的自动重新渲染
  2. 只有state值发生变化时,组件才会重新渲染
  3. 当state的值是一个对象时,修改时是使用新的对象去替换已有对象
  4. 当通过setState去修改一个state时,并不表示修改当前的state,修改的是组件下一次渲染时state值
  5. setState()会触发组件的重新渲染,它是异步的

        - 所以当调用setState()需要用旧state的值时,一定要注意

        - 有可能出现计算错误的情况

        - 为了避免这种情况,可以通过为setState()传递回调函数的形式来修改state值

3.2 类组件中state统一存储到了实例对象的state属性中

  • 可以通过 this.state 来访问
  • 通过 this.setState() 对其进行修改
  • 当我们通过 this.setState() 修改state时,React只会修改设置了的属性

 App.js


import React from "react";
class App extends React.Component {
    state = {
        count: 0,
        name: 'hahh',
        other: {
            age: 18,
            gender: 'w'
        }
    }
    // 必须用箭头函数,保证this指向
    handleCilck = () => {
        // this.setState({ count: 2 })
        // 会有异步的问题
        // this.setState({ count: this.state.count + 1 })

        // prevState 是一个对象
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        });

    }

    handleCilckOther = () => {
        // other会从两个属性变成一个属性,因为other没有直接存储到state中
        // this.setState({ other: { gender: 'm' } })
        this.setState({
            other: { ...this.state.other, gender: 'm' }
        });
    }
    render() {
        return <div className="items">
            <div>{this.state.count}</div>
            <div>{this.state.name}</div>
            <div>{this.state.other.age}</div>
            <div>{this.state.other.gender}</div>
            <button onClick={this.handleCilck}>点击</button>
            <button onClick={this.handleCilckOther}>改变other</button>
        </div>
    }
}
export default App

3.3 区别:

  • 函数组件中,响应函数直接以函数的形式定义在组件中
  • 在类组件中,响应函数是以类的方法来定义,之前的属性都会保留,但是这你仅限于直接存储于state中的属性

4. React 获取DOM对象

4.1 函数组件 从React处获取DOM对象 useRef()

1. 创建一个存储DOM对象的容器

          - 使用 useRef() 钩子函数

            钩子函数的注意事项:

                       ① React中的钩子函数只能用于函数组件或自定义钩子

                       ② 钩子函数只能直接在函数组件中调用

2. 将容器设置为想要获取DOM对象元素的ref属性

<div ref={divRef}>....</div>

const divRef= useRef()

   - React会自动将当前元素的DOM对象,设置为容器current属性

        返回的就是一个普通的JS对象 {current:undefined}

    *       - 所以我们直接创建一个js对象,也可以代替useRef()

    *       - 区别:

    *           我们创建的对象,组件每次重新渲染都会创建一个新对象

    *           useRef()创建的对象,可以确保每次渲染获取到的都是同一个对象

    *       - 当你需要一个对象不会因为组件的重新渲染而改变时,就可以使用useRef()

import React, { useRef } from "react";

const App = () => {
    const divRef = useRef() // 创建一个容器
    const handleChange = () => {

        // 原生的DOM对象
        // document.getElementById('haha').innerText = "哈哈哈哈"

        // react中的DOM对象
        console.log(divRef.current)
        divRef.current.innerText = "哈哈哈哈"
    }
    return <div className="items">
        <div id="haha" ref={divRef}>hhhhh</div>
        <button onClick={handleChange}>改变div里面的内容</button>
    </div>

}
export default App

4.2 类组件使用 React.createRef() 获取DOM

1.创建一个属性,用来存储DOM对象

divRef = React.createRef();

  2.将这个属性设置为指定元素的ref值

<div ref={divRef}>....</div>

import React, { Component } from 'react'

class App extends Component {
    divRef = React.createRef()
    handleChange = () => {

        // 原生的DOM对象
        // document.getElementById('haha').innerText = "哈哈哈哈"

        // react中的DOM对象
        console.log(this.divRef.current, 'lei')
        this.divRef.current.innerText = "哈哈哈哈"
    }
    render() {
        return <div className="items">
            <div id="haha" ref={this.divRef}>hhhhh</div>
            <button onClick={this.handleChange}>改变div里面的内容</button>
        </div>
    }

}
export default App

 学习笔记,只为了记录!!!

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值