React組件的創(chuàng)建與state同步異步詳解
組件的創(chuàng)建
類組件
類組件是指使用ES6中class定義的組件稱為類組件
導(dǎo)入類組件時 組件名首字母必須大寫
類組件必須要繼承React.Component父類(相關(guān)方法和屬性均會被繼承)
render為固定函數(shù)(必須有),有返回值,返回類組件的結(jié)構(gòu)(jsx)
??定義類組件并暴露
import React from 'react'
//App為類名 可隨意起 繼承 React.Component(固定,不可丟掉)
class App extends React.Component{
render(){
render(){
//1.return若要回車必須加上()
//2.最外層只能有一個標(biāo)簽,不能有兄弟并列
return (
<section>
hello react
<ul>
<li>1111</li>
<li>222</li>
</ul>
<div>新的內(nèi)容111</div>
<div>新的內(nèi)容2222</div>
</section>
)
}
}
}
export default App //導(dǎo)出:方便被其他組件引用
??在src下的 index.js入口文件中導(dǎo)入 需要的App類組件
React 17之前版本
import React from 'react'
import ReactDOM from 'react-dom'
import App from "./01-base/01-class組件" //引入時必須大寫
ReactDOM.render(<App></App>,document.getElementById("root"))
......................................
React 18版本
import {createRoot} from 'react-dom/client'
import App from "./01-base/01-class組件" //導(dǎo)入App組件
const container = document.getElementById('root')
const root = createRoot(container); //App放入的位置
root.render(<App/>) //單雙標(biāo)簽均可以
函數(shù)式組件
function App(){
return (
<div>
hello functional component
<div>111</div>
<div>2222</div>
</div>
)
}
export default App
組件的嵌套
import React, { Component } from 'react'
class Child extends Component{
render(){
return <div>child</div>
}
}
class Navbar extends Component{
render(){
return (
<div>
navbr
<Child></Child>
</div>
)
}
}
function Swiper(){
return <div>swiper</div>
}
const Tabbar = ()=> <div>tabbar</div>
//以上3種子組件的形式 均可進行嵌套
export default class App extends Component {
render() {
return (
<div>
<Navbar></Navbar>
<Swiper></Swiper>
<Tabbar></Tabbar>
</div>
)
}
}
........................................
import App from "./01-base/03-組件的嵌套"
import {createRoot} from 'react-dom/client'
const container = document.getElementById('root')
const root = createRoot(container);
root.render(<App/>)
組件的樣式
推薦使用行內(nèi)樣式,因為React覺得每個組件都是一個獨立的整體
行內(nèi)樣式
想給虛擬dom添加行內(nèi)樣式,需要使用表達式傳入樣式對象的方式來實現(xiàn)
render() {
var myname = 'xiaoming'
var isChecked = false
var obj = {
backgroundColor:"yellow",
fontSize:""http://駝峰命名法
}
return (
<div>
{myname}-{10+20}-歲
{10>20?"a":"b"}
<div style={obj}>111</div>
<div style={style={{textDecoration:isChecked?"line-through":''}}>
//這里有兩個括號,第一個表示我們再要JSX里插入了JS了,第二個是對象的括號
<div style={{background:"red"}}>222</div>
</div>
)
}
??1. {}里面為js表達式,不支持語句
??2. 行內(nèi)樣式需要寫入一個樣式對象如上面的obj,這個樣式對象的位置可以放在很多地方,例如render函數(shù)里、組件原型上、外鏈js文件中
class樣式
- css文件中寫入樣式
- 導(dǎo)入css文件
- 為元素添加class類名(class需要寫成className,在寫類js代碼,會受到j(luò)s規(guī)則的存在,而class為關(guān)鍵字)
<div className="active">333</div> <div id="myapp">444</div>
???? ?? class ==> className,for ===> htmlFor(label) ???? ??
<label htmlFor='username'>用戶名:</label> <input type="text" id="username"></input>
事件處理
事件綁定
??render內(nèi)使用箭頭函數(shù)— 直接使用this
a = 100
render(){
return(
<button onClick={ ()=>{
console.log("click1","如果處理邏輯過多不推薦",this.a);
} }>add1</button>
)
}
箭頭函數(shù)作用域為App,所以this直接為App
??render內(nèi)調(diào)用函數(shù),函數(shù)普通函數(shù) – 使用bind改變this指向
a = 100
render(){
return(
{/* call,apply改變this指向并自動執(zhí)行函數(shù);bind改變this指向不自動執(zhí)行 */}
<button onClick={ this.handleClick2.bind(this)}>add2-不推薦</button>
)
}
handleClick2(){
console.log("click2",this.a)
}
render內(nèi)剛開始 this 為 undefined,通過使用 bind 將this指向改為App
??render內(nèi)調(diào)用函數(shù),函數(shù)箭頭函數(shù) – 直接使用this
a = 100
render(){
return(
<button onClick={ this.handleClick3 }>add3-比較推薦</button>
)
}
handleClick3 = ()=>{
console.log("click3",this.a)
}
??render內(nèi)使用箭頭函數(shù)調(diào)用函數(shù) – 直接使用this
a = 100
render(){
return(
{/* 非常推薦 */}
<button onClick={ ()=>{
this.handleClick4()
} }>add4</button>
{/* 執(zhí)行匿名函數(shù)后調(diào)用handleClick4 */}
)
}
handleClick4 = ()=>{
console.log("click4",this.a)
}
onClick里面的this為App,所以當(dāng)handleClick被調(diào)用時不論是箭頭函數(shù)還是普通函數(shù)this均和調(diào)用者相同都為App
事件的參數(shù)傳遞
??1. 在render里調(diào)用方法的地方外面包一層箭頭函數(shù)
??2. 在render里通過this.handleClick.bind(this,參數(shù))來傳遞
??3. 通過event傳遞
ref的應(yīng)用
??給標(biāo)簽設(shè)置ref=“mytext”
<input ref="mytext"></input>
<button onClick={ ()=>{
console.log("click1",this.refs.mytext.value);
} }>add1</button>
通過 this.refs.mytext,ref可以獲取到應(yīng)用的真實dom
?? 給組件設(shè)置ref="username
通過這個獲取 this.refs.username ,ref可以獲取到組件對象
??新的寫法(嚴(yán)格模式下)
myref = React.createRef()
<input ref={this.myref}></input>
<button onClick={ ()=>{
console.log("click",this.myref.current.value);
} }>add1</button>
訪問 this.myref.current
狀態(tài)(state)
狀態(tài)就是組件描述某種顯示情況的數(shù)據(jù),由組件自己設(shè)置和更改,也就是說組件自己維護,使用狀態(tài)的目的就是為了在不同的狀態(tài)下是組建的顯示不同(自己管理)
定義state
state={
mytext:"收藏",
myShow:true
}
render(){
return(
<div>
<h1>welcome</h1>
<button onClick={()=>{
//this.state.mytext = "取消收藏" 不用直接修改state
}}>{this.state.mytext}</button>
</div>
)
}
this.state是純js對象,在vue中,data屬性利用Object.defineProperty處理過的,更改data的數(shù)據(jù)的時候回出發(fā)數(shù)據(jù)的getter和setter,但是React中沒有這樣的處理,如果直接更改,react無法得知,所以需要使用setState間接修改
setState
myShow存放在實例的state對象當(dāng)中,組件的render函數(shù)內(nèi),會根據(jù)組件的state的中的myShow不同 顯示“取消”或“收藏”
可以一次更新多個狀態(tài)
import React, { Component } from 'react'
export default class App extends Component {
// state={
// mytext:"收藏",
// myShow:true
// }
constructor(){
super()//必須寫
this.state={
mytext:"收藏",
myShow:true,
myName:"xiaoming"
}
}
// ?。。?!以上兩種state寫法均可以!!!
render() {
return (
<div>
<h1>welcome--我的名字是{this.state.myName}</h1>
<button onClick={()=>{
//this.state.mytext = "取消收藏" 不用直接修改state
this.setState({
//mytext:"取消收藏"
myName:'zhangsan',
myShow:!this.state.myShow
})//間接修改state
if(this.state.myShow){
console.log("收藏邏輯");
}else{
console.log("取消邏輯");
}
}}>{this.state.myShow?'收藏':'取消收藏'}</button>
</div>
)
}
}
setState同步異步
- setState處在同步的邏輯中,異步更新狀態(tài),更新真實dom
- setState處在異步的邏輯中,同步更新狀態(tài),同步更新真實dom
- setState接受第二個參數(shù),第二個參數(shù)回調(diào)函數(shù),狀態(tài)和dom更新后就會被觸發(fā)
補充-React面試題
react事件綁定和普通事件綁定的區(qū)別
React并不會真正的綁定事件到每一個具體的《》元素上,而是采用事件代理的模式,綁定在根節(jié)點身上
Event對象
和普通瀏覽器一樣,事件handler會被自動傳入一個event對象,這個對象和普通的瀏覽器event對象所包含的方法和屬性基本一致。不同的是React中的event對象并不是瀏覽器提供的,而是自己內(nèi)部構(gòu)建的。他同樣具有event.stopPropagation、event.preventDefalut這種常用方法
到此這篇關(guān)于React組件的創(chuàng)建與state同步異步詳解的文章就介紹到這了,更多相關(guān)React組件的創(chuàng)建內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React Native可復(fù)用 UI分離布局組件和狀態(tài)組件技巧
這篇文章主要為大家介紹了React Native可復(fù)用 UI分離布局組件和狀態(tài)組件使用技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Express+React+Antd實現(xiàn)上傳功能(前端和后端)
這篇文章主要介紹了Express+React+Antd實現(xiàn)上傳功能(前端和后端),本文通過示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2024-04-04
在React中使用React.createRef:更優(yōu)雅的DOM引用方式
React提供了多種方式來引用DOM元素,其中React.createRef()是一種更為現(xiàn)代、更優(yōu)雅的方式,在這篇文章中,我們將深入了解React.createRef()的應(yīng)用,以及它為開發(fā)者帶來的便利,感興趣的朋友一起看看吧2024-01-01

