1. 組件化封裝的結構
- 1.1. 定義一個類(組件名必須是大寫,小寫會被認為是html元素), 繼續自
React.Component
- 1.2. 實現當前組件的
render函數
render當中返回的jsx內容
,就是之后React
會幫助我們渲染的內容
- 1.3. 結構圖如下:
data 方法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
- 類似于
constructor(props) {super()this.state = {message: 'hello World'}// 對需要綁定的方法,提前綁定好thisthis.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
-
class App extends React.Component {constructor () {super()this.state = {message: 'hello world',counter: 100}}render () {const { message } = this.statereturn (<div><h2>{ message }</h2></div>)}}```
-
-
函數組件:
-
function 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><aclassName="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的語法
。 - 完整代碼如下:
<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. 完整代碼:
<!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 完整代碼如下:
-
<!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.statereturn (<div><h2>{ message }</h2></div>)}}// 2. 創建root并且渲染App組件const root = ReactDOM.createRoot(document.querySelector('#root'))root.render(<App/>)</script></body></html>