1. 组件化封装的结构
-
1.1. 定义一个类(组件名必须是大写,小写会被认为是html元素), 继续自
React.Component
-
1.2. 实现当前组件的
render函数
render当中返回的jsx内容
,就是之后React
会帮助我们渲染的内容
-
1.3. 结构图如下:
jsdata 方法 render() // 具体渲染的内容
2. 组件化-数据依赖
组件化问题:数据在那里定义
?
- 2.1. 在组件中的数据,可以分成两类:
参与界面更新的数据
:当数据变化时,需要更新组件渲染的内容不参与界面更新的数据
:当数据变化时,不需要更新组件渲染的内容
- 2.2. 参与姐妹更新的数据又称为
参与数据流
,这个数据定义在当前对象的state
中- 在构造函数中
this.state = { 定义的数据 }
- 当数据发生变化时,可以调用
this.setState
({更新的数据})来更新数据,并且通知React进行update操作
- 在进行
update操作
时,就会重新调用render函数
,并且使用最新的数据,来渲染界面。
- 在进行
- 在构造函数中
3. 组件化-事件绑定
- 3.1. 组件化问题二: ·事件绑定中的this·
- 在
类中直接定义一个函数
,并且将这个函数绑定到元素的onClick事件
上,当前这个函数的this指向是undefined
- 在
- 3.2.
默认情况下是undefined
:(因为在babel转化成严格模式
或者ES6语法中类是严格模式
,严格模式下,this指向undefined
)- 很奇怪,居然是
undefined
- 因为在
正常的DOM操作
中,监听点击,监听函数中的this指向其实节点对象(比如说button对象)
- 这次因为
React并不是直接渲染成真实的DOM
,编写的button只是一个语法糖
,它的本质是React的Element对象
; - 那么在这里发生监听时,
react在执行函数时并没有绑定this, 默认情况下就是一个undefined
- 很奇怪,居然是
- 3.3. 在绑定的函数中,可能想要使用当前对象,比如执行
this.setState函数
,就必须拿到当前对象的this
-
就需要在传入函数时,给这个函数绑定
this
-
类似于
javascriptconstructor(props) { super() this.state = { message: 'hello World' } // 对需要绑定的方法,提前绑定好this this.btnClick = this.btnClick.bind(this) } {/* 写法一:bind(this) */} {/* <button onClick={this.btnClick.bind(this)}>修改文本</button> */} {/* 写法二:统一在构造函数中绑定this, 函数调用的时候不用bind(this) */} <button onClick={this.btnClick}>修改文本</button>
-
4. React数据事件处理
- 4.1. 如果
原生DOM
有一个监听事件,我们可以如何操作- 方式一:获取
DOM原生
,添加监听事件 - 方式二:在
HTML
原生中,直接绑定onclick
;
- 方式一:获取
- 4.2. 在
React
中是如何操作呢?React的事件监听
,主要有两点不同:React事件
的命名采用小驼峰式(camelCase)
, 而不是纯小写- 需要通过
{}
传入一个事件处理函数,这个函数会在事件发生时被执行;
5. React组件的分类重构代码
- 5.1. 组件分为:类组件和函数组件
-
类组件:
class App extends React.Component
jsclass App extends React.Component { constructor () { super() this.state = { message: 'hello world', counter: 100 } } render () { const { message } = this.state return ( <div> <h2>{ message }</h2> </div> ) } }```
-
函数组件:
jsfunction App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;
-
5. 编写Hello_React
案例
-
5.1. 第一步:在界面上通过React显示一个Hello World
- 注意:编写
React的script代码
中,必须添加type="text/babel"
, 作用是可以让babel解析jsx的语法
。 - 完整代码如下:
javascript<script type="text/babel"> const root = ReactDOM.createRoot(document.querySelector('#root')) // 将文本定义成变量 let message = 'hello World' const root = ReactDOM.createRoot(document.querySelector('#root')) root.render(<h2>{message}/h2>) </script>
-
5.2.
ReactDOM.createRoot函数
:用于创建一个React根
,之后的渲染的内容会包含在这个根中。参数
:将渲染的内容,挂载到哪个HTML元素上根元素
:id为root的元素
-
5.3.
root.render()
- 参数:要渲染的根组件
-
5.4. 完整代码:
javascript<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="root"></div> <!-- 1. CDN引入 --> <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <!-- 2. 编写React代码 --> <script type="text/babel"> const root = ReactDOM.createRoot(document.querySelector('#root')) // 将文本定义成变量 let message = 'hello World' // 监听按钮的点击 function btnClick () { // 1.1 修改数据 message = '你好啊 李银河' // 1.2. 重新渲染界面(原因:React默认情况下不会重新执行渲染界面的, React是没有黑魔法的,黑魔法:所有东西都是可见的) rootRender() } // 3. 封装一个渲染函数 function rootRender () { // 使用()把所有的html括号包裹起来,代表的是一个整体 root.render(( <div> <h1>{message}</h1> <button onClick={btnClick}>修改文本</button> </div> )) } rootRender() </script> </body> </html>
- 注意:编写
6. 使用组件重构代码
- 6.1 完整代码如下:
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="../lib/react.js"></script>
<script src="../lib/react-dom.js"></script>
<script src="../lib/babel.js"></script>
<script type="text/babel">
// 1.定义App根组件
class App extends React.Component {
constructor () {
super()
this.state = {
message: 'hello world',
counter: 100
}
}
render () {
const { message } = this.state
return (
<div>
<h2>{ message }</h2>
</div>
)
}
}
// 2. 创建root并且渲染App组件
const root = ReactDOM.createRoot(document.querySelector('#root'))
root.render(<App/>)
</script>
</body>
</html>