react函数组件的props,ref,state。

           react开发我们会把页面分为一个个组件,组件是独立而且可复用的重复代码片段。具体来说组件可以是一个按钮,一个输入框。react组件有两种定义方法,一种是函数组件,一种是类组件。我们这里说一下函数组件之间父子之间如何传递props参数,如果通过ref来获取真实DOM元素,如何通过设置state这个react变量去动态展示页面中的数据。

 1.props

import React from 'react'
import LogItem from './LogItem'
import './Log.css'
export default function Logs() {//模拟一组从服务器加载的数据const logsData = [{id: "001",data: new Date(2021, 9, 20, 19, 0),title: '学习九阳神功',time: 30},{id: "002",data: new Date(2021, 4, 20, 19, 0),title: '学习我我我功',time: 20},{id: "003",data: new Date(2021, 5, 20, 19, 0),title: '学习你你神功',time: 10},{id: "004",data: new Date(2022, 1, 20, 19, 0),title: '学习九大大滴神功',time: 34}]return (// 如果组件中的数据全部写死会导致组件无法动态设置//希望组件数据可以由外部设置 在组件间父组件可以通过props给子组件传递数据<div className='logs'>{/* 在父组件给子组件设置属性在函数组件中可以通过参数来保存 */}{logsData.map((item) => {return (<LogItem key={item.id} data={item.data} title={item.title} time={item.time} />// <LogItem {...item} />)})}</div>)
}

        这里我们在组件中定义了一个数组对象,作为服务器返回的json数据。我们想要一个列表去展示这些数据,每个列表都是相同的,所以我们需要一个子组件展示内容,父组件遍历展示子组件就可以了。我们需要把数据传给子组件,通过props传递方法就是之间传,通过key=value这种方式直接传递,key不会作为参数,会作为内部特殊属性保留。然后传递过去之后子组件去获取然后展示。 

import React from 'react'
import MyDate from './MyDate'
import './LogItem.css'
export default function LogItem(props) {// console.log(props);// console.log(props.data);return (//函数组件的行参定义一个props props指向一个对象 包含父组件传递所有参数<div className="item"><MyDate data={props.data} /><div className="content"><h2 className='title'>{props.title}</h2><div className="time">{props.time}</div></div></div>)
}

       函数组件直接在参数里面props接收就可以了。输出的props就是传过来的那些props参数。然后{}里面写表达式就可以动态展示了。props是父组件给子组件传递的方式。

2.ref

        我们在开发用react框架开发时,如果需要操作真实DOM,我们可以通过DOM对象(document)去操作DOM,也可以直接从react获取DOM对象,首先用钩子函数useRef()去创建一个存储DOM对象的容器,其实就是一个非常普通的对象,里面有一个current属性仅此而已。

import React, { useRef } from 'react'
import './App.css'
import { useState } from 'react'
let temp
export default function App() {console.log('函数执行了');const h1Ref = useRef()//创建一个容器// const h1Ref = { current: undefined }console.log(temp === h1Ref);temp = h1Ref//这里永远不相等因为每次都是生成新对象//直接用这种创建一个有current属性的对象也可以console.log(h1Ref);const clickHandler = () => {// const header = document.getElementById('header')// alert(header)// header.innerHTML = '哈哈'//原生DOM操作DOM元素h1Ref.current.innerHTML = 'hah'}return (<div className='app'><h1>{a}</h1><h1 id='header' ref={h1Ref}>为上标题</h1><button onClick={add}>加</button><h1>{user.name}-----{user.age}</h1><button onClick={go}>2</button><button onClick={clickHandler}>点完</button></div>)
}

        比如我们希望用按钮去操作h1标签里面的文本改变,用document操作就需要设置id,然后通过id获取元素对象赋值给header,然后调用header.innerText=‘haha’ ,但是我们在react尽量避免使用dom因为会脱离react掌控。我们这里用钩子函数去定义一个容器h1Ref然后给我们想要操作的DOM一个ref属性值是容器,那么就存到了这个容器对象的current里面,控制台可以看,而且只是一个简单的js对象。我们可以直接定义一个对象去代替,属性就是current。然后直接h1Ref.current.innerHTML='hha'操作h1的文本内容,只不过需要注意的是useRef()创建的容器只会生成一次,如果直接创建对象的话每次重新渲染都需要重新生成一个新的对象。所以如果我们需要保持一个不变的对象或者值,多次渲染不丢失重置就可以用uesRef比如我们关闭定时器用到的id

function MyComponent() {const timerRef = useRef(null); // 创建一个持久的容器对象useEffect(() => {timerRef.current = setInterval(() => console.log('hi'), 1000);}, []);return <button onClick={() => clearInterval(timerRef.current)}>停止</button>;
}

3.state 

        当我们想要设置一个变量,而且这个变量动态的展示到页面上面,我们就需要去用钩子函数useState()去创建一个数组,前面是我们的变量,后面是一个函数,调用之后可以用回调函数去更新我们的变量。

        


import React, { useRef } from 'react'
import './App.css'
import { useState } from 'react'
let temp
export default function App() {console.log('函数执行了');console.log(h1Ref);// let a =1let [a, setA] = useState(2)console.log(useState());//输出的是一个数组前面是初始值后面是函数const result = useState(1)console.log(result);let fn = result[1]console.log('fn', fn)const [user, setUser] = useState({ name: 'sun', age: 11 })//点击加数字增加 点击减数字减少const add = () => {// a++// setA(a++)setA((preState) => {return preState + 1})}const go = () => {// user.name = 'gou'// setUser(user) //不会重新渲染因为修改的是原对象// const newUser = Object.assign({}, user)// newUser.name = 'gou'// setUser(newUser)//这个方法可以因为浅复制给一个新对象复制,地址是改变的// setUser({ name: 'zhu', age: 19 })setUser({ ...user, name: 'gou' })}return (<div className='app'><h1>{a}</h1><h1 id='header' ref={h1Ref}>为上标题</h1><button onClick={add}>加</button><h1>{user.name}-----{user.age}</h1><button onClick={go}>2</button><button onClick={clickHandler}>点完</button></div>)
}

        我们如果直接let a = 1 然后我们点击按钮其实a改变了,但是页面a不会改变,因为没有重新渲染页面。所以a++执行成功但是页面a没有变化,这时候我们用我们的钩子函数useState()并且用数组结构的方法去设置a。然后我们调用setA这个方法,里面设置一个回调函数,preState是当前的变量a,然后返回更新后的新的变量a。然后重新调渲染页面。

        

        state特点。1.state是一个被react管理的变量 通过setState()修改变量的值会触发重新渲染,重新调用一个render(),然后重新diff比较之后更新然后用DOM转化虚拟DOM对象为真实DOM,只有state发生变化才会重新渲染。state是一个对象 修改时使用新的对象替换已有对象,直接修改原有对象 不会生效因为地址没变,当通过setState去修改一个state时不表示修改当前state,修改的是组件下一次渲染的state值。

        2.setState()会触发组件重新渲染 它是异步的,会排队让同步代码执行完以后再执行重新渲染,所以当调用setState()需要用到旧state值一定要注意 有可能出现计算错误的情况,为了避免这种情况可以传递回调函数的形式 箭头函数参数为当前最新的state

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87694.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87694.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ARM+FPGA实现的BISS-C协议解决方案,适用于高精度光栅位移传感器等

模块简介 本资源提供了专为FPGA设计的BISS-C接口协议发送模块源码。BISS-C模式作为一种高速、同步的串行通信协议&#xff0c;广泛应用于高精度光栅位移传感器的数据传输中&#xff0c;特别适用于需要精确位置信息的应用场景。此模式遵循主从架构&#xff0c;其中FPGA作为主控制…

spring中@Transactional注解和事务的实战理解附代码

文章目录 前言一、事务是什么&#xff1f;二、事务的特性2.1隔离性2.2事务的隔离级别 三、Transactional注解Transactional注解简介基本用法常用属性配置事务传播行为事务隔离级别异常处理与回滚性能优化建议 四、 事务不生效的可能原因方法访问权限非public自调用问题异常被捕…

替代进口SCA7606【智芯微】国产高精度电流传感器 工业新能源电网专用

SCA7606&#xff08;智芯微&#xff09;产品解析与推广文案一、产品概述SCA7606 是 智芯微电子&#xff08;ZXMICRO&#xff09; 推出的一款 高精度数字隔离式电流传感器芯片&#xff0c;采用 霍尔效应数字输出 技术&#xff0c;专为 工业控制、新能源、智能电网 等领域的电流检…

Java 与 Vue 全栈开发:“一课一得“ 学习笔记系统实战

一、项目背景与核心价值 "一课一得" 是一个面向学习者的笔记管理平台&#xff0c;旨在帮助用户系统化记录、整理和回顾学习内容。项目采用前后端分离架构&#xff1a;前端基于 Vue.js 构建交互式界面&#xff0c;后端使用 Java Spring Boot 实现业务逻辑&#xff0c…

百度文心大模型 4.5 开源深度测评:技术架构、部署实战与生态协同全解析

声明&#xff1a;本文只做实际测评&#xff0c;并非广告 1.前言 2025 年 6 月 30 日&#xff0c;百度做出一项重大举措&#xff0c;将文心大模型 4.5 系列正式开源&#xff0c;并选择国内领先的开源平台 GitCode 作为首发平台。该模型也是百度在2025年3月16日发布的自研的新一…

力扣_链表_python版本

一、206. 反转链表代码&#xff1a; class Solution:def reverseList(self, head):dummy ListNode()cur headwhile cur:last cur.nextcur.next dummy.nextdummy.next curcur lastreturn dummy.next二、92. 反转链表 IIclass Solution:def reverseBetween(self, head: Opt…

[netty5: WebSocketProtocolHandler]-源码分析

在阅读这篇文章前&#xff0c;推荐先阅读&#xff1a;[netty5: MessageToMessageCodec & MessageToMessageEncoder & MessageToMessageDecoder]-源码分析 WebSocketProtocolHandler WebSocketProtocolHandler 是 WebSocket 处理的基础抽象类&#xff0c;负责管理 Web…

[2025CVPR]一种新颖的视觉与记忆双适配器(Visual and Memory Dual Adapter, VMDA)

引言 多模态目标跟踪&#xff08;Multi-modal Object Tracking&#xff09;旨在通过结合RGB模态与其他辅助模态&#xff08;如热红外、深度、事件数据&#xff09;来增强可见光传感器的感知能力&#xff0c;尤其在复杂场景下显著提升跟踪鲁棒性。然而&#xff0c;现有方法在频…

理想汽车6月交付36279辆 第二季度共交付111074辆

理想汽车-W(02015)发布公告&#xff0c;2025年6月&#xff0c;理想汽车交付新车36279辆&#xff0c;第二季度共交付111074辆。截至2025年6月30日&#xff0c;理想汽车历史累计交付量为133.78万辆。 在成立十周年之际&#xff0c;理想汽车已连续两年成为人民币20万元以上中高端市…

MobileNets: 高效的卷积神经网络用于移动视觉应用

摘要 我们提出了一类高效的模型&#xff0c;称为MobileNets&#xff0c;专门用于移动和嵌入式视觉应用。MobileNets基于一种简化的架构&#xff0c;利用深度可分离卷积构建轻量级的深度神经网络。我们引入了两个简单的全局超参数&#xff0c;能够有效地在延迟和准确性之间进行…

SDP服务发现协议:动态查询设备能力的底层逻辑(面试深度解析)

SDP的底层逻辑揭示了物联网设备交互的本质——先建立认知,再开展协作。 一、SDP 核心知识点高频考点解析 1.1 SDP 的定位与作用 考点:SDP 在蓝牙协议栈中的位置及核心功能 解析:SDP(Service Discovery Protocol,服务发现协议)位于蓝牙协议栈的中间层,依赖 L2CAP 协议传…

CppCon 2018 学习:GIT, CMAKE, CONAN

提到的&#xff1a; “THE MOST COMMON C TOOLSET” VERSION CONTROL SYSTEM BUILDING PACKAGE MANAGEMENT 这些是 C 项目开发中最核心的工具链组成部分。下面我将逐一解释每部分的作用、常见工具&#xff0c;以及它们如何协同构建现代 C 项目。 1. VERSION CONTROL SYSTEM&am…

使用tensorflow的线性回归的例子(五)

我们使用Iris数据&#xff0c;Sepal length为y值而Petal width为x值。import matplotlib.pyplot as pltimport numpy as npimport tensorflow as tffrom sklearn import datasetsfrom tensorflow.python.framework import opsops.reset_default_graph()# Load the data# iris.d…

虚幻基础:动作——蒙太奇

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 动作——蒙太奇如果动作被打断&#xff0c;则后续的动画通知不会执行 动作——蒙太奇 如果动作被打断&#xff0c;则后续的动画通知不会执行

[工具系列] 开源的 API 调试工具 Postwoman

介绍 随着 Web 应用的复杂性增加&#xff0c;API 测试已成为开发中不可或缺的一部分&#xff0c;无论是前端还是后端开发&#xff0c;确保 API 正常运行至关重要。 Postman 长期以来是开发者进行 API 测试的首选工具&#xff0c;但是很多基本功能都需要登陆才能使用&#xff…

【力扣 简单 C】746. 使用最小花费爬楼梯

目录 题目 解法一 题目 解法一 int min(int a, int b) {return a < b ? a : b; }int minCostClimbingStairs(int* cost, int costSize) {const int n costSize; // 楼顶&#xff0c;第n阶// 爬到第n阶的最小花费 // 爬到第n-1阶的最小花费从第n-1阶爬上第n阶的花费…

python+django开发带auth接口

pythondjango开发带auth接口 # coding utf-8 import base64 from django.contrib import auth as django_authfrom django.core.exceptions import ObjectDoesNotExist from django.http import JsonResponsefrom sign.models import Eventdef user_auth(request):"&quo…

RBAC权限模型如何让API访问控制既安全又灵活?

url: /posts/9f01e838545ae8d34016c759ef461423/ title: RBAC权限模型如何让API访问控制既安全又灵活? date: 2025-07-01T04:52:07+08:00 lastmod: 2025-07-01T04:52:07+08:00 author: cmdragon summary: RBAC权限模型通过用户、角色和权限的关联实现访问控制,核心组件包括用…

安达发|告别低效排产:APS高级排程如何助力电池企业智造升级?

在全球能源转型的背景下&#xff0c;动力电池、储能电池等市场需求快速增长&#xff0c;电池制造企业面临着订单波动大、工艺复杂、交期严格等挑战。传统的手工排产或基于ERP的简单计划模式已难以满足高效、精准的生产需求。APS高级排程通过智能算法优化生产计划&#xff0c;实…

数据结构20250620_数据结构考试

试卷01 天津金海通软件笔试题 选择题(4*416) 对于双向循环链表,在p指针所指的结点之后插入s指针所指结点的操作应为 p->nexts; s->prip; p->next->pris; s->nextp->nextp->nexts; p->next->pris; s->prip; s->nextp->nexts->pri …