react综合(未完)
根组件包裹子组件
React 组件是返回标签的 JavaScript 函数
组件化思想的应用:
-
有了组件化的思想,我们在之后的开发中就要充分的利用它。
-
尽可能的将页面拆分成一个个小的、可复用的组件。
-
这样让我们的代码更加方便组织和管理,并且扩展性也更强。
React的组件相对于Vue更加的灵活和多样,按照不同的方式可以分成很多类组件:
-
根据组件的定义方式,可以分为:
函数组件
(Functional Component )和类组件
(Class Component); -
根据组件内部是否有状态需要维护,可以分成:
无状态组件
(Stateless Component )和有状态组件
(Stateful Component); -
根据组件的不同职责,可以分成:
展示型组件
(Presentational Component)和容器型组件(逻辑组件)
(Container Component);
这些概念有很多重叠,但是他们最主要是关注数据逻辑和UI展示的分离:
-
函数组件、无状态组件、展示型组件主要关注
UI的展示
-
类组件、有状态组件、容器型组件主要关注
数据逻辑
React中组件的注意事项:
-
在
html
中是不严格区分大小写
的,也就是说h2
写成H2
,div
写成DIV
, 在html中都是可以被正常解析的但是在
JSX
中,标签是严格区分大小写
的, 因为在JSX
中首字母大写的标签会被认为是组件去进行解析,所以
H2
在JSX
中是不会被作为h2
去进行解析的,而是会作为组件去进行解析,但是我们并没有名其H2
的组件,所以此时就会报
H2 is not defined
的错误 -
无论是函数式组件还是类组件,其返回的jsx
只能有一个根组件
,如果有多个根组件,react就不知道具体需要渲染哪一个组件为主
,如果的确需要返回多个组件,可以使用
数组
作为render函数
的返回值
export default
:JavaScript 的 export
关键字使此函数可以在此文件之外访问。default
关键字表明它是文件中的主要函数。
类组件
类组件的定义有如下要求
-
组件的名称是
大写字符
开头(无论类组件还是函数组件
) -
类组件需要
继承
自React.Component
-
类组件
必须实现render函数
, 以告诉react框架需要在页面上渲染什么结构和什么内容,rander (){ return{} }
return 出去的是一个大括号,意味着返回的是一个js对象,因此不能直接在return里写html。故出现了jsx的语法(原生js的扩展)。
用()在js里面写html,用{}在html里面写js。
要求将return{}
的{}
改为()
,并且只能有一个根元素,
注意
-
1.组件名必须首字母大写
-
2.虚拟DOM元素只能有一个根元素
-
3.虚拟DOM元素必须有结束标签
渲染类组件标签的基本流程
-
1.React内部会创建组件实例对象
-
2.调用render()得到虚拟DOM, 并解析为真实DOM
-
3.插入到指定的页面元素内部
函数组件
三大核心属性
-
state
-
state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
-
组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
tips:
-
1.组件中render方法中的this为组件实例对象
-
2.组件自定义的方法中this为undefined,如何解决?
-
a)强制绑定this: 通过函数对象的bind()
-
b)箭头函数
-
-
3.状态数据,不能直接修改或更新
-
props
-
1.每个组件对象都会有props(properties的简写)属性
-
2.组件标签的所有属性都保存在props中
作用:
-
1.通过标签属性从组件外向组件内传递变化的数据
-
2.注意: 组件内部不要修改props数据
-
refs与事件处理
constructor/super
在 React 组件中,constructor
方法通常用于初始化组件的状态(state)和绑定事件处理方法。
在构造函数中,需要首先调用 super(props)
,它是 Component
类的构造函数。这是为了在子类(你的组件)中继承父类的所有属性和方法,并确保正确地设置组件的上下文。通过调用 super(props)
,你可以使用 this.props
来访问组件的属性。
在构造函数中,你可以使用 this.state
来初始化组件的状态对象。状态是组件的可变数据,当状态发生变化时,React 会重新渲染组件。通过在构造函数中设置 this.state
,你可以为组件提供初始状态。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0
};
}
componentDidMount(){
fetch('###')
.then(res => res.json)
//.then(json => console.log(json.result))
.then(json => {
}
console.log(json.result))
}
render() {
return (
<div>
<p>Counter: {this.state.counter}</p>
<button onClick={this.handleClick}>Increment</button>
</div>
);
}
}
Tips:
如果直接用赋值的方式修改对象属性,对象属性所属的内存位置是不会改变的。
PureComponent
把继承类从 Component 换成 PureComponent 即可
可以减少不必要的 render 操作的次数,主要目的就是防止不必要的子组件渲染更新,从而提高性能。
PureComponent原理
当组件更新时,如果组件的 props 和 state 都没发生改变,
hooks
等价的class示例
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
UseState
import React, { useState } from 'react';
function Example() {
// 声明一个叫 “count” 的 state 变量。
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
在这里,useState
就是一个 Hook (等下我们会讲到这是什么意思)。通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 state。useState
会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。它类似 class 组件的 this.setState
,但是它不会把新的 state 和旧的 state 进行合并。(我们会在
useState
唯一的参数就是初始 state。在上面的例子中,我们的计数器是从零开始的,所以初始 state 就是 0
。值得注意的是,不同于 this.state
,这里的 state 不一定要是一个对象 —— 如果你有需要,它也可以是。这个初始 state 参数只有在第一次渲染时会被用到。
useState的一些注意事项
-
类型值初始化
初始化 useState
的首选方法是将预期的数据类型传递给它,以避免潜在的空白页错误。例如,一个空对象,如下所示,可以传递给状态:
import { useState } from "react";
function App() {
// 使用期望的数据类型初始化状态
const [user, setUser] = useState({});//初始化为{}
// 渲染 UI
return (
<div className='App'>
<img src={user.image} alt='profile image' />
<p>User: {user.name}</p>
<p>About: {user.bio}</p>
</div>
);
}
export default App;
甚至更进一步,在初始化状态时定义用户对象的预期属性:
import { useState } from "react";
function App() {
// 使用期望的数据类型初始化状态
const [user, setUser] = useState({
image: "",
name: "",
bio: "",
});
// 渲染 UI
return (
<div className='App'>
<img src={user.image} alt='profile image' />
<p>User: {user.name}</p>
<p>About: {user.bio}</p>
</div>
);
}
export default App;
-
没有使用可选链
当尝试通过使用点(.
)操作符通过相关对象来访问该对象,例如 user.names.firstName
。但是,如果丢失了任何链接的对象或属性,就会出现问题。页面将中断,用户将得到一个空白页错误。
import { useState } from "react";
function App() {
// 使用期望的数据类型初始化状态
const [user, setUser] = useState({});
// 渲染 UI
return (
<div className='App'>
<img src={user.image} alt='profile image' />
<p>User: {user?.names?.firstName}</p>
<p>About: {user.bio}</p>
</div>
);
}
export default App;
例如 user.names && user.names.firstname
,它只在左侧表达式为真(如果 user.names
存在)时计算右侧表达式。然而,这个解决方案很混乱,因为它需要对每个对象链进行多次检查。
使用可选的链接操作符(?.
),你可以读取深埋在相关对象链中的属性值,而不需要验证每个引用的对象是否有效。可选的链接操作符(?.
)就像点链接操作符(.
),不同的是,如果引用的对象或属性缺失(即 null
或 undefined
),表达式短路并返回 undefined
值。简单地说,如果丢失了任何链接对象,它就不会继续进行链接操作(短路)。
例如,user?.names?.firstname
不会抛出任何错误或中断页面,因为一旦它检测到 user
或 names
对象丢失,它将立即终止操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!