基礎配置導入所需的react文件
<!-- react框架文件 -->
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- react用來渲染頁面的文件 -->
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 用來編譯jsx語法的庫 -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
- html模板
- ReactDOM.render()
- JSX 語法
- 組件 & props
- props & 純函數
- 綁定事件
- bind
- 列表渲染
- 條件渲染
- this.state
- style和class
- 生命周期
- 表單
- 獲取真實的DOM節點
- this.props.children
1&2 在DOM節點(app)中渲染所需的標簽(html)
ReactDOM.render(a,b)
參數1: a代表HTML的東西
參數2: b代表渲染的節點
<body>
<!-- 渲染的div -->
<div id="app">
</div>
<script type="text/babel">
ReactDOM.render(
//第一個參數(html)
<h3>hellow,world</h3>,
// 第二個參數,節點
document.querySelector('#app')
)
</script>
</body>
3. JSX 語法
JSX 就是用來聲明 React 當中的元素。(html)
JSX 是在 JavaScript 內部實現的。
{}里執行js代碼<>執行html代碼
<body>
<div id="app">
</div>
<script type="text/babel">
//聲明一個對象
const person={
name:'hxt',
age:21
}
//聲明一個常量 為html(jsx)
const element=
<div>
<h3>名字:{person.name}</h3>
<h3>年齡:{person.age}</h3>
</div>
//將值放入所需的參數位置
ReactDOM.render(
element,
document.getElementById('app')
)
</script>
</body>
4. 組件 & props
這里需要用到es6的繼承類(所繼承的類將會有繼承的類的東西)
使用class
聲明一個類(類為大寫開頭,所繼承的類開頭也為大寫)
類里不是個對象,后面不需要寫逗號
1.構造器,初始化實例(可接受參數)
-
super()
(固定)將父類中的this對象繼承給子類 - new類后將會執行一次
constructor
2.class Xxx extends Aaa
類Xxx繼承Aaa
示例代碼
<script>
//定義一個類
class Person{
constructor(){
this.mouth = '1張';
this.leg='兩條';
}
eat(){
console.log('你真能吃')
}
speak(){
console.log('你真能說')
}
}
var person = new Person();
console.log(person)
//繼承
class Man extends Person {
constructor(name,age) {
// 執行父類構造器
super();
this.name = name;
this.age = age;
}
}
var man = new Man('張三',100);
console.log(man);
console.log(man.leg);
man.speak();
</script>
react示例代碼
1.聲明一個子類,需要繼承 (注意大寫)
-
需要返回子組件所放置html的地方(相當于vue的
template
)
3.將聲明繼承的類組件 放入ReactDOM.render()
參數1里
<body>
<div id="app">
</div>
<script type="text/babel">
//定義一個子組件繼承react的組件
class Person extends React.Component{
//構造器,初始化實例
constructor(props){
//接受參數(固定)將父類中的this對象繼承給子類
super(props)
}
//渲染的子組件(相當于vue的template)
render(){
//需用return返回
return(
//使用{}來使用JS代碼
<h3>
<div>名字:{this.props.name}</div>
<div>年齡:{this.props.age}</div>
</h3>
)
}
}
ReactDOM.render(
//整個div為父組件,Person標簽為子組件,Person 里傳參數
<div>
<div>你好呀</div>
<hr/>
<Person name="hxt" age="21"/>
</div>,
document.getElementById('app')
)
</script>
</body>
5.props & 純函數
純函數即為不受外界影響,值可以確定的函數
純函數
sum(a,b){
return a+b
}
sum(1,2)
sum(1,2)
sum(1,2)
sum(1,2)
不純的函數(不確定的值)
let abc=1
sum(a,b){
abc++
return a*b+abc
}
sum(1,2)
sum(1,2)
sum(1,2)
6.綁定事件
bind(綁定所指向的this)
<script>
var person = {
language: '粵語',
speak() {
console.log(this);
console.log(`他會講${this.language}`);
}
}
person.speak();
// 使用bind綁定函數執行時的this
var speak = person.speak.bind(person);
speak();
</script>
onClick(C為大寫)
<body>
<div id="app">
</div>
<script type="text/babel">
class Demo extends React.Component {
constructor(props) {
super(props)
//綁定this指向
this.num = this.num.bind(this)
}
render() {
return (
<div>
<ul>
<li><button onClick={() => { this.num(1001) }}>點擊1</button></li>
<li><button onClick={() => { this.num(1002) }}>點擊2</button></li>
<li><button onClick={() => { this.num(1003) }}>點擊3</button></li>
</ul>
</div>
)
}
num(data) {
alert(data)
}
}
ReactDOM.render(
<Demo />,
document.querySelector('#app')
)
</script>
</body>
7. 列表渲染
1.利用數組的map來渲染頁面
2.es6解構
3.傳入參數list
<div id="app">
</div>
<script type="text/babel">
//定義一個子組件繼承react的組件
class Person extends React.Component{
//構造器,初始化實例
constructor(props){
//接受參數(固定)將父類中的this對象繼承給子類
super(props)
}
//渲染的子組件(相當于vue的template)
render(){
// let list = this.props.list;
let {list} = this.props
//需用return返回
return(
//使用{}來使用JS代碼
<ul>
{
//使用map來渲染列表
list.map((item,index)=>{
return(
<li key={index}>{item.name}</li>
)
})
}
</ul>
)
}
}
const list=[
{
name:'hxt',
age:21
},
{
name:'cc',
age:22
},
{
name:'hh',
age:18
},
{
name:'aa',
age:11
}
];
ReactDOM.render(
<Person list={list}/>,
document.getElementById('app')
)
</script>
用state數據來渲染
1.生命周期(componentDidMount...)
2.設置state
3.axios
4.更改state
5.數組map渲染
class HotFilm extends React.Component{
constructor(props){
super(props)
this.state={
filmList:[]
}
}
componentDidMount() {
const url="http://huruqing.cn:3000/api/film/getList"
axios.get(url).then(res=>{
console.log(res)
this.setState({
filmList:res.data.films
})
}).catch(err=>{
console.log(err)
})
}
render(){
let {filmList} =this.state
return(
<ul className="list">
{
filmList.map(item=>{
return (
<li className="item flex jc-sb pt-15" key={item.filmId}>
<div className="film flex jc-sa ml-10">
<img src={item.poster} className="image "/>
<div className="ml-10 lh15">
<p className="f16">{item.name} <span className="type">{JSON.parse(item.filmType).name}</span></p>
<p className="f14 gray">觀眾評分 <span className="yellow">{item.grade}</span> </p>
<p className="f14 gray actor">主演:{item.actorStr}</p>
<p className="f14 gray">{item.nation} | {item.runtime}分鐘</p>
</div>
</div>
<div className="buttbox">
<button className="butt mr-10">購票</button>
</div>
</li>
)
})
}
</ul>
)
}
}
8. 條件渲染
1.利用三目運算來選擇是否顯示html
例:是否顯示樣式
<div className={pageName==='index'?"flex2 fcc active":"flex2 fcc gray"}>
<i className=" f20 iconfont icon-shouye"></i>
<p className="f12">首頁</p>
</div>
9. this.state
利用this.state來存放數據(相當于vue的data)
constructor() {
super()
this.state = {
list: []
}
}
修改state值需用 this.setState({})
例如
this.setState = {
list: [1,2,3]
}
10. style和class
1.style
<div style={{border:'1px solid red'}}></div>
2.class
react的class是用className來替代的
index-default-page是個類
<div className="index-default-page"></div>
11. 生命周期
1、getDefaultProps()
設置默認的props,也可以用dufaultProps設置組件的默認屬性.
2、getInitialState()
在使用es6的class語法時是沒有這個鉤子函數的,可以直接在constructor中定義this.state。此時可以訪問this.props
3、componentWillMount()
組件初始化時只調用,以后組件更新不調用,整個生命周期只調用一次,此時可以修改state。
4、 render()
react最重要的步驟,創建虛擬dom,進行diff算法,更新dom樹都在此進行。此時就不能更改state了。
5、componentDidMount()
組件渲染之后調用,只調用一次。
更新
6、componentWillReceiveProps(nextProps)
組件初始化時不調用,組件接受新的props時調用。
7、shouldComponentUpdate(nextProps, nextState)
react性能優化非常重要的一環。組件接受新的state或者props時調用,我們可以設置在此對比前后兩個props和state是否相同,如果相同則返回false阻止更新,因為相同的屬性狀態一定會生成相同的dom樹,這樣就不需要創造新的dom樹和舊的dom樹進行diff算法對比,節省大量性能,尤其是在dom結構復雜的時候
8、componentWillUpdata(nextProps, nextState)
組件初始化時不調用,只有在組件將要更新時才調用,此時可以修改state
9、render()
組件渲染
10、componentDidUpdate()
組件初始化時不調用,組件更新完成后調用,此時可以獲取dom節點。
卸載
11、componentWillUnmount()
組件將要卸載時調用,一些事件監聽和定時器需要在此時清除。
12. 表單(當函數不傳值就進行接收時接收的為此時的狀態)(ev.target為當前函數標簽的內容)
class Person extends React.Component{
//構造器,初始化實例
constructor(props){
//接受參數(固定)將父類中的this對象繼承給子類
super(props)
this.login=this.login.bind(this)
this.state={
username:'hxt',
passwd:'123'
}
}
//渲染的子組件(相當于vue的template)
render(){
let {username,passwd} = this.state
//需用return返回
return(
<div>
<input name="username" value={username} onChange={this.login}/>
<input name="passwd" value={passwd} onChange={this.login}/>
</div>
)
}
login(ev){
console.log(ev);
console.log(ev.target);
let target = ev.target;
let name = target.name;
this.setState({
[name]: ev.target.value
})
}
}
ReactDOM.render(
<Person />,
document.getElementById('app')
)
13. 獲取真實的DOM節點
ref屬性
ref可以掛載到組件上也可以是dom元素上;
掛到組件(class聲明的組件)上的ref表示對組件實例的引用。不能在函數式組件上使用 ref 屬性,因為它們沒有實例:
掛載到dom元素上時表示具體的dom元素節點。