【React】组件&事件
React(二)
创建组件
函数组件
函数组件:使用JS的函数或者箭头函数创建的组件
- 使用 JS 的函数(或箭头函数)创建的组件,叫做
函数组件
- 约定1:函数名称必须以大写字母开头,React 据此区分
组件
和普通的 HTML
- 约定2:函数组件必须有返回值,表示该组件的 UI 结构
// 1. 导包
import React from 'react'
import ReactDom from 'react-dom/client'
// 2. 创建 函数式组件
// 普通函数或者箭头函数创建组件,首字母大写
// 组件必须要有返回值
function Music() {
return (
<div>
<h1>haha</h1>
</div>
)
}
const VNode = (
<div>
<Music></Music>
</div>
)
// 3. 挂载
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
类组件
类组件:使用 ES6 的 class 创建的组件,叫做类(class)组件
- 约定1:类名称也必须以大写字母开头
- 约定2:类组件应该继承
React.Component
父类,从而使用父类中提供的方法或属性 - 约定3:类组件必须提供
render
方法 - 约定4:render 方法必须有返回值,表示该组件的 UI 结构
// 1. 导包
import React from 'react'
import ReactDom from 'react-dom/client'
// 2.
class Hello extends React.Component {
render() {
return <h1>哈哈</h1>
}
}
const VNode = (
<>
<Hello></Hello>
</>
)
// 3. 挂载
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
组件提取到单独的文件中
-
在
components
文件夹下,创建函数组件hello.js
,类组件home.js
,- hello.js
const Hello = () => <h1>我是hello组件</h1> export default Hello
- home.js
import React from 'react' class Home extends React.Component { render() { return <h2>home</h2> } } export default Home
-
在
index.js
中导入
// 1. 导包
import React from 'react'
import ReactDom from 'react-dom/client'
// 导入组件
import Hello from './components/hello'
import Home from './components/home'
// 2. 创建虚拟DOM
const App = (
<>
<Hello></Hello>
<Home></Home>
</>
)
// 3. 挂载
ReactDom.createRoot(document.querySelector('#root')).render(App)
有状态组件 无状态组件
状态即数据。
- 函数组件又叫做
无状态组件
函数组件是不能自己提供数据 【前提:基于hooks之前说的 16.8之前】 - 类组件又叫做
有状态组件
类组件可以自己提供数据,数据如果发生了改变,内容会自动的更新 - 组件的私有数据也称为状态 ,当组件的状态发生了改变,页面结构也就发生了改变。【数据驱动视图】
- 函数组件是没有状态的,只负责页面的展示(静态,不会发生变化)性能比较高
- 类组件有自己的状态,负责更新UI,只要类组件的数据发生了改变,UI就会发生更新(动态)。
- 在复杂的项目中,一般都是由函数组件和类组件共同配合来完成的。
// 1. 导包
import React from "react"
import ReactDom from 'react-dom/client'
// 函数组件 没有状态 仅仅做一些数据展示的工作,可以使用函数组件
// function App() {
// return (
// <div>我是组件</div>
// )
// }
// 类组件 有状态 如果有状态,状态需要切换,更新视图 用类组件
class App extends React.Component {
render() {
return (
<h1>我是类组件</h1>
)
}
}
const VNode = (
<div>
<App></App>
</div>
)
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
类组件的状态
- 状态
state
即数据,是组件内部的私有数据,只有在组件内部可以使用 - state的值是一个对象,表示一个组件中可以有多个数据
- 通过
this.state.xxx
来获取状态
// 1. 导包
import React from "react"
import ReactDom from 'react-dom/client'
// 类组件 有状态 如果有状态,状态需要切换,更新视图 用类组件
class App extends React.Component {
// state节点中提供状态
// 通过 this.state.xxx 来获取状态
state = {
name: 'Tt',
age: 17
}
render() {
return (
<h1>{this.state.name} ----- {this.state.age}</h1>
)
}
}
const VNode = (
<div>
<App></App>
</div>
)
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
事件处理
注册事件
语法:on+事件名={事件处理程序}
比如onClick={this.handleClick}
// 1. 导包
import React from "react"
import ReactDom from 'react-dom/client'
// 类组件 有状态 如果有状态,状态需要切换,更新视图 用类组件
class App extends React.Component {
// state节点中提供状态 通过 this.state.xxx 来获取状态
state = {
name: 'Tt',
age: 17
}
// 提供一些方法
handleClick() {
console.log('点击');
}
render() {
return (
<div>
<button onClick={this.handleClick}>按钮</button>
</div>
)
}
}
const VNode = (
<div>
<App></App>
</div>
)
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
阻止默认事件
// 1. 导包
import React from 'react'
import ReactDom from 'react-dom/client'
// 类组件 有状态 如果有状态,状态需要切换,更新
class App extends React.Component {
// state节点中提供状态
// 通过 this.state.xxx 来获取状态
state = {
name: 'Tt',
age: 17,
}
// 提供方法
handleClick(e) {
console.log('点击qqq')
console.log(e) // e是react合成的事件对象
e.preventDefault() // 阻止默认行为
}
render() {
return (
<div>
{/* 方法后面不加小括号,因为加了小括号表示函数就执行啦 */}
<button onClick={this.handleClick}>按钮</button>
<a href="www.baidu.com">百度一下</a>
</div>
)
}
}
const VNode = (
<div>
<App></App>
</div>
)
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
this指向
render
里面的this指向app
组件
render
外面的指向undefined
// 1. 导包
import React from 'react'
import ReactDom from 'react-dom/client'
// 类组件 有状态 如果有状态,状态需要切换,更新视图 用类组件
class App extends React.Component {
// 提供一些方法
handleClick() {
console.log(this) // undefined
}
render() {
**console.log(this) //App组件**
return (
<div>
{/* this指向的是App组件 */}
{/* 这并不是函数的调用,仅仅是做了一个赋值 onClick = this.handleClick */}
<button onClick={this.handleClick}>按钮</button>
</div>
)
}
}
const VNode = (
<div>
<App></App>
</div>
)
ReactDom.createRoot(document.querySelector('#root')).render(VNode)
解决this指向问题
通过上面的this指向我们可以看到,点击按钮时this会指向undefined
。解决这个问题方法如下:
-
写成箭头函数
<button onClick={(e) => this.handleClick(e)}>按钮</button>
-
使用bind将this修改
onClick={this.handleClick.bind(this)}
<button onClick={this.handleClick.bind(this)}>按钮</button>
-
直接修改handleClick函数,将其改为箭头函数
- 但是,这种方式不能传参
handleClick = (e) => { console.log('handleClick: ', this, e) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现