1.一個(gè)普通的 構(gòu)造函數(shù)就是 組件
function Hello(props ) {
// props 所有的屬性都是只讀的
// 接受父組件傳遞過來的參數(shù)
// 結(jié)論:不論是 vue 還是 React 組件中的props 永遠(yuǎn)都是只讀的,不能重新賦值
// 如何在一個(gè)組件中 return 一個(gè)null ,表示組件是空的,什么都不會(huì)渲染
// return null
//在組件中,必須返回一個(gè)合法的 JSX 虛擬DOM 元素
let name = props.name // 大黃
return <div>這是Hell哦哦哦</div>
}
// 給組件傳遞參數(shù) 在組件上加屬性
let name = '大黃'
ReactDOM.render(
<Hello name={name}></Hello>
,document.getElementById('app')
)
給組件傳遞props 參數(shù)步驟:
1.給組件添加屬性,使用 <Hello name={name}></Hello>
let dog = {
name :'基督教',
age:18,
}
// 方式一
<Hello name={dog.name} age = {dog.age}>
</Hello>
// 方式二
<Hello (...dog)>
</Hello>
2.在組件構(gòu)造函數(shù)中接受參數(shù)function Hello(props ) {} 參數(shù)在props對(duì)象中 props 是只讀的
2 創(chuàng)建一個(gè)JSX文件
1 創(chuàng)建一個(gè) Demo.jsx文件
import React from 'react'; // 創(chuàng)建組件,虛擬DOM元素,生命周期
//我們看到,代碼中除了開頭引入時(shí)出現(xiàn)了React,其它地方都沒有其蹤影。但是當(dāng)去掉import React from "react"時(shí),程序卻會(huì)執(zhí)行出錯(cuò)ReferenceError: React is not defined。
// 為什么每個(gè)函數(shù)組件需要引入 react 因?yàn)?我們的JSX語法只是一種語法糖,它最終會(huì)被轉(zhuǎn)譯成純粹的js語法,因此在babel轉(zhuǎn)譯之后,我們的代碼就變成了:
//比如
const App = () => (
<div>Hello World!!!</div>
);
//轉(zhuǎn)譯后的
var App = function App() {
return React.createElement(
"div",
null,
"Hello World!!!"
);
};
function Demo(props) {
return <div>這是一個(gè)組件</div>
}
// 把組件導(dǎo)出
export default Demo
2.然后在需要使用組件的地方引入組件
// 默認(rèn),如果不做單獨(dú)的配置,不能省略 .jsx 后綴名
import React from 'react'; // 創(chuàng)建組件,虛擬DOM元素,生命周期
import ReactDOM from 'react-dom' ;//把創(chuàng)建好的組件和虛擬DOM放到頁面上展示的
import Demo from './../components/Demo.jsx'
ReactDOM.render(
<div>
<Hello name={name}></Hello>
<Demo></Demo>
</div>
,document.getElementById('app')
)
如果想省略.jsx 后綴名的話 需要配置 webpack
在webpack.config.js 加入 resolve
module.exports = {
mode:'production' ,//development production
//在 webpack 4.x 中。有個(gè)很大的特性,就是約定大于配置 約定,默認(rèn)打包入口路徑是 src -> index.js
//那些node 支持 chrome 支持的就行
plugins:[
htmlPlugin
],
module: { //所有第三方 模塊的配置規(guī)則
rules: [
{ test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/ }
// 千萬不要忘記加 exclude 排除選項(xiàng)
]
},
resolve:{
extensions:['.js','.jsx','.json'] ,//表示這幾個(gè)文件的后綴名,可以省略不寫,這幾個(gè)位置很重要 按順序補(bǔ)全的
alias:{
'@':path.join(__dirname,"./src") // 配置別名
}
}
}
3 將組件用Class 創(chuàng)建
import React from 'react'; // 創(chuàng)建組件,虛擬DOM元素,生命周期
import ReactDOM from 'react-dom' ;//把創(chuàng)建好的組件和虛擬DOM放到頁面上展示的
// 如果要使用 class 定義組件,必須讓自己的組件,繼承自React.Component
// class 組件名稱 extends React.Component{
//
// // 在組件內(nèi)部,必須有 render 函數(shù)
//
// render(){
//
// //render 函數(shù)中,必須返回合法的 JSX 虛擬 DOM 結(jié)構(gòu)
// return <div>jskdksk</div>
// }
// }
var arr = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
class Movie extends React.Component {
constructor(){
// 由于Movie組件,繼承了 React.Component 這個(gè)父類,所以自定義的構(gòu)造器中,必須調(diào)用super()
super()
this.state = {
msg :'大家好我是 Movie 私有組件'
} // 這個(gè) this.state={} 就相當(dāng)于 Vue 中的 data(){return{}}
}
render() {
// return null
// 在class 關(guān)鍵字 創(chuàng)建 的組件中,如果要使用 外界傳遞過來的 props 參數(shù),不需要接收,直接通過哦this.props.****來接收
return <div>
這是 movie
{
arr.map((item) => {
return <div>{item}</div>
})
}
{/*{注意在 class 組件中 this 指向當(dāng)前組件的實(shí)例對(duì)象}*/}
<div>{this.props.name}</div>
{/*{state私有數(shù)據(jù)}*/}
<div>{this.state.msg}</div>
</div>
}
}
export default Movie
3 兩種創(chuàng)建組件方式的對(duì)比
注意:使用class 關(guān)鍵字創(chuàng)建的組件,有自己的私有數(shù)據(jù) 和生命周期
注意:使用function 創(chuàng)建的組件,只有props ,沒有自己私有數(shù)據(jù)和生命周期函數(shù)。
class 創(chuàng)建出來的 state 可讀可寫
1.用構(gòu)造函數(shù)創(chuàng)建出來的組件:叫做無狀態(tài)組件(無狀態(tài)組件今后用的不多)
2.用class 關(guān)鍵字創(chuàng)建出來的組件:叫做有狀態(tài)組件
有狀態(tài)組件和無狀態(tài)組件之間的本質(zhì)區(qū)別就是:有誤state 屬性,和有無生命周期
3:什么情況下使用有狀態(tài)組件?什么情況下使用無狀態(tài)組件?
如果一個(gè)組件需要自己的私有數(shù)據(jù),則推薦使用Class 創(chuàng)建的 有狀態(tài)組件
如果一個(gè)組件不需要私有數(shù)據(jù),則推薦使用:無狀態(tài)組件
React 官方說:無狀態(tài)組件,由于沒有state和 生命周期函數(shù) 所以運(yùn)行效率會(huì)比有狀態(tài)組件快一些
4.組件中的 props 和 state/data 之間的區(qū)別
props 中的數(shù)據(jù)都是外界傳過來的
state/data 中的數(shù)據(jù),都是組件私有的
props中的數(shù)據(jù)都是只讀的,不能重新賦值
state/data中的數(shù)據(jù)都是可度可寫的