React基礎(chǔ)

react

他是一個(gè)用于構(gòu)建用戶界面的 JavaScript 庫(kù)

React-安裝

  1. 安裝 nodeJS
  2. 安裝create-react-app
npm install -g create-react-app

創(chuàng)建項(xiàng)目

create-react-app myreact
// myreact 項(xiàng)目名稱

啟動(dòng)項(xiàng)目

    cd myreact
    yarn start
    // npm run start

默認(rèn)項(xiàng)目地址:http://localhost:3000/

React文件結(jié)構(gòu)和JSX語(yǔ)法

第一個(gè)react項(xiàng)目

打開 src/App.js 刪除默認(rèn)代碼 得到 hello react

import React, { Component } from 'react';
//導(dǎo)入React和 React.Component

class App extends Component {
// App根組件繼承 React.compoent  

  render() {
// 渲染 并返回一段html結(jié)構(gòu)
    return (
      <div className="App">
        <h1>你好react</h1>
      </div>
    );

  }
}

export default App;
//導(dǎo)出默認(rèn) App根組件

JSX語(yǔ)法

JSX 是一個(gè)看起來(lái)很像 html 的 JavaScript 語(yǔ)法擴(kuò)展。

js和html混合

1. 只能有一個(gè)根節(jié)點(diǎn)

return (
  <div className="App">
    <h1>你好react</h1>
  </div>
);

// Classname="App" 就是根節(jié)點(diǎn)

2. 可以執(zhí)行javascript表達(dá)式 {}

{1+1}   
{i == 1 ? '對(duì)的!' : '錯(cuò)誤的'}

3. 類名class 變成 className

<div className="App">
 </div>

4. 行內(nèi)樣式 展開

var myStyle = {
  "font-size": "14px",
  "color": "#FF0000"
}
return (

  <div className="App">
    <h1 style={myStyle}>你好react</h1>
  </div>

);

5. 注釋 {/* 注釋 */}

6. 數(shù)組里面可以直接寫html節(jié)點(diǎn)

var arr = [
  <h1>組件渲染</h1>,
  <h1>虛擬dom</h1>
]
return (
  <div className="App">
   {arr}
  </div>
);

組件

可以這么說(shuō),一個(gè) React 應(yīng)用就是構(gòu)建在 React 組件之上的。

創(chuàng)建組件 Child.js

import React,{Component} from 'react'
export default class Child extends Component{
    render(){
        return (
            <div className="child">
                    <h1>我是子組件</h1>
                    <hr/>
            </div>
        );
    }
}

調(diào)用組件

01. 導(dǎo)入組件

import Child from './components/Child.js'

02 使用組件

return (
  <div className="App">
    <Child/>
    <h1>App根組件</h1>    
  </div>
);

完成代碼

import React, { Component } from 'react';

import Child from './components/Child.js'
// 導(dǎo)入組件

class App extends Component { 
  render() {
    return (
      <div className="App">
        <Child/>
        <h1>App根組件</h1>    
      </div>
    );
  }
}

export default App;
//導(dǎo)出默認(rèn) App根組件

React State(狀態(tài))

state 是組件的當(dāng)前狀態(tài),可以把組件簡(jiǎn)單看成一個(gè)“狀態(tài)機(jī)”,根據(jù)狀態(tài) state 呈現(xiàn)不同的 UI 展示。 一旦狀態(tài)(數(shù)據(jù))更改,組件就會(huì)自動(dòng)調(diào)用 render 重新渲染 UI,這個(gè)更改的動(dòng)作會(huì)通過(guò) this.setState 方法來(lái)觸發(fā)。

初始化組件 state

添加一個(gè)類構(gòu)造函數(shù)來(lái)初始化狀態(tài) this.state

constructor() {  
    super();  //調(diào)用父對(duì)象構(gòu)造函數(shù)
    this.state={name:"dandan",age:18}
  }

使用state

return (
    <div className="App">
        大家好我是{this.state.name}今年{this.state.age}歲了
    </div>
  );

完整代碼

import React, { Component } from 'react';

class App extends Component { 
  constructor() {  
    super();  
    this.state={name:"dandan",age:18}
  }
  render() {
    return (
      <div className="App">
          大家好我是{this.state.name}今年{this.state.age}歲了
      </div>
    );
  }
}

export default App;

React Props

state 和 props 主要的區(qū)別在于 props 是不可變的,而 state 可以根據(jù)與用戶交互來(lái)改變。這就是為什么有些容器組件需要定義 state 來(lái)更新和修改數(shù)據(jù)。 而子組件只能通過(guò) props 來(lái)傳遞數(shù)據(jù)。

傳遞prop給子組件

return (
<div className="App">
  <Child name="dandan"/>
  <Child name="段鵬"/>
  <Child />
</div>
);

子組件使用props

import React, { Component } from 'react';
import Child from './components/Child'

class App extends Component {
  render() {
    return (
      <div className="App">
      <Child name="dandan"> </Child>
      <Child name="段鵬"></Child>
      <Child ></Child>
      </div>
    );
  }
}

export default App;

完整代碼

App.js

import React, { Component } from 'react';
import Child from './components/Child'

class App extends Component {
  render() {
    return (
      <div className="App">
      <Child name="dandan"> </Child>
      <Child name="段鵬"></Child>
      <Child ></Child>
      </div>
    );
  }
}

export default App;

Child.js

import React,{Component} from 'react'
export default class Child extends Component{

    render(){
        return (
            <div className="child">
                    <h1>我是子組件 我的名字是{this.props.name}</h1>
                    <hr/>
            </div>
        );
    }
}
Child.defaultProps = {
    name:"保密"
}
// props 默認(rèn)值

事件處理

React 元素的事件處理和 DOM 元素類似

React 事件綁定屬性的命名采用駝峰式寫法,而不是小寫。

如果采用 JSX 的語(yǔ)法你需要傳入一個(gè)函數(shù)作為事件處理函數(shù),而不是一個(gè)字符串(DOM 元素的寫法)

javascript寫法

<button onclick="showMsg()">
  按鈕
</button>

react寫法

<button onClick={showMsg}">
  按鈕
</button>

完整react代碼

import React, { Component } from 'react';
class App extends Component {  
  showMsg(){
    alert("來(lái)自react問(wèn)候!");
  }
  render() {

    return (
      <div className="App">
        <button onClick={this.showMsg}>按鈕</button>     
      </div>
    );
  }
}

export default App;

setState 改變r(jià)eact狀態(tài)

import React, { Component } from 'react';

class App extends Component {  
  constructor(props) {
    super(props);
    this.state = {num:1}
  }
  addNum(){
    this.setState({num:this.state.num+1})
  }
  render() {     
    return (

{this.state.num}

        {this.addNum()}}>按鈕     

    );
  }
}

export default App;

用箭頭函數(shù)是為了保證函數(shù)里面this的正確指向br 你也可以用bind方法

按鈕

React 表單雙向綁定

import React, { Component } from 'react';
class App extends Component {  
  constructor(props) {
    super(props);
    this.state = {num:1}
  }
  changeNum(e){
    this.setState({num:e.target.value})
  }
  render() {     
    return (
      <div className="App">
      <input type="text" value={this.state.num} onChange={this.changeNum.bind(this)}/>
      <h1>{this.state.num}</h1>
      </div>
    );
  }
}

export default App;

動(dòng)態(tài)的添加更改class

import React, { Component } from 'react';
import './App.css';
class App extends Component {  
  constructor(props) {
    super(props);
    this.state = {bg:'red'}
  }
  changeClass(e){
    this.setState(pre=>{
      return ({bg:pre.bg==='red'?'blue':'red'});
    })
  }
  render() {     
    return (
      <div className="App">
        <button className={this.state.bg} onClick={this.changeClass.bind(this)}>按鈕</button>
      </div>
    );
  }
}

export default App;

添加style

render() {   
    var css = {
      borderRadius:"6px",
      padding:"8px 16px",
      color:'#fff',
      background:'blue'
    }  
    return (
      <div className="App">
        <button style={css}>按鈕</button>
      </div>
    );
  }
      }

React 條件渲染

條件性地渲染一塊內(nèi)容

三目運(yùn)算符號(hào)

render() {
    var isLogin = true;
    return (
      <div className="App">
        {isLogin?'歡迎您回來(lái)主人':'請(qǐng)登陸'}      
      </div>
    );
  }

& &運(yùn)算符

在 JavaScript 中,true && expression 總是返回 expression,而 false && expression 總是返回 false。
因此,如果條件是 true,&& 右側(cè)的元素就會(huì)被渲染,如果是 false,React 會(huì)忽略并跳過(guò)它。

render() {
    var isLogin = false;
    return (
      <div className="App">
        {isLogin &&'歡迎您回來(lái)主人'}      
      </div>
    );
  }

列表渲染

我們可以使用 JavaScript 的 map() 方法來(lái)創(chuàng)建列表。

初始化列表數(shù)據(jù)

constructor(props) {
    super(props);
    this.state={
      list:[{name:'vue'},{name:'react'},{name:'angular'}]
    }
  }

map渲染列表

return (
      <div className="App">

        {this.state.list.map(
          (item,index)=>{
            return (
              <div key={index}>{item.name}</div>
            )
          }
        )}

      </div>
    );

完整代碼

import React, { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props);
    this.state={
      list:[{name:'vue'},{name:'react'},{name:'angular'}]
    }
  }

  render() {
    return (
      <div className="App">        
        {this.state.list.map(
          (item,index)=>{
            return (
              <div key={index}>{item.name}</div>
            )
          }
        )}      
      </div>
    );
  }
}

export default App;

Key 可以在 DOM 中的某些元素被增加或刪除的時(shí)候幫助 React 識(shí)別哪些元素發(fā)生了變化。因此你應(yīng)當(dāng)給數(shù)組中的每一個(gè)元素賦予一個(gè)確定的標(biāo)識(shí)。
一個(gè)元素的 key 最好是這個(gè)元素在列表中擁有的一個(gè)獨(dú)一無(wú)二的字符串。通常,我們使用來(lái)自數(shù)據(jù)的 id 作為元素的 key:
元素沒有確定的 id 時(shí),你可以使用他的序列號(hào)索引 index 作為 key:

組件生命周期

組件的生命周期可分成三個(gè)狀態(tài):

Mounting:已插入真實(shí) DOM
Updating:正在被重新渲染
Unmounting:已移出真實(shí) DOM


image

componentWillMount 
在渲染前調(diào)用,在客戶端也在服務(wù)端。一般用的比較少,更多的是用在服務(wù)端渲染

1、組件剛經(jīng)歷constructor,初始完數(shù)據(jù)
2、組件還未進(jìn)入render,組件還未渲染完成,dom還未渲染

componentDidMount 
在第一次渲染后調(diào)用,只在客戶端。之后組件已經(jīng)生成了對(duì)應(yīng)的DOM結(jié)構(gòu),可以通過(guò)this.getDOMNode()來(lái)進(jìn)行訪問(wèn)。 如果你想和其他JavaScript框架一起使用,可以在這個(gè)方法中調(diào)用setTimeout, setInterval或者發(fā)送AJAX請(qǐng)求等操作(防止異步操作阻塞UI)。

組件第一次渲染完成,此時(shí)dom節(jié)點(diǎn)已經(jīng)生成,可以在這里調(diào)用ajax請(qǐng)求,返回?cái)?shù)據(jù)setState后組件會(huì)重新渲染

componentWillReceiveProps 
在組件接收到一個(gè)新的 prop (更新后)時(shí)被調(diào)用。這個(gè)方法在初始化render時(shí)不會(huì)被調(diào)用。

shouldComponentUpdate 
返回一個(gè)布爾值。在組件接收到新的props或者state時(shí)被調(diào)用。在初始化時(shí)或者使用forceUpdate時(shí)不被調(diào)用。 
可以在你確認(rèn)不需要更新組件時(shí)使用。

componentWillUpdate
在組件接收到新的props或者state但還沒有render時(shí)被調(diào)用。在初始化時(shí)不會(huì)被調(diào)用。

componentDidUpdate
 在組件完成更新后立即調(diào)用。在初始化時(shí)不會(huì)被調(diào)用。

componentWillUnmount
在組件從 DOM 中移除之前立刻被調(diào)用。

class Demo extends Component {
    constructor(props, context) {
            //如果想(在組件其他地方是可以直接接收的)使用props或context,則需要以參數(shù)形式傳入。
            //只要組件存在constructor,就必要要寫super,否則this指向會(huì)錯(cuò)誤
            super(props, context);
            this.state = {
                data: 1
            };
    },
    componentWillMount () {
        // 在組件掛載之前調(diào)用,且全局只調(diào)用一次。如果在這個(gè)鉤子里可以setState,render后可以看到更新后的state,不會(huì)觸發(fā)重復(fù)渲染。
        // 該生命周期可以發(fā)起異步請(qǐng)求,并setState。(React v16.3后廢棄該生命周期,可以在constructor中完成設(shè)置state)
        // 不推薦在這里發(fā)起ajax請(qǐng)求,若返回?cái)?shù)據(jù)為空,則容易造成界面空白,影響渲染效果
    },
    componentDidMount () {
        //組件第一次渲染完成,此時(shí)dom節(jié)點(diǎn)已經(jīng)生成,可以在這里調(diào)用ajax請(qǐng)求,返回?cái)?shù)據(jù)setState后組件會(huì)重新渲染
    },
    componentWillReceiveProps (nextProps) {
        // 在接受父組件改變后的props需要重新渲染組件時(shí)用到的比較多
        // 通過(guò)對(duì)比nextProps和this.props,將nextProps setState為當(dāng)前組件的state,從而重新渲染組件
        nextProps.data !== this.props.data && this.setState({
            data: nextProps.data
            },() => {
              console.log("new data...");
        });

    },
    shouldComponentUpdate (nextProps, nextState) {
        // react性能優(yōu)化非常重要的一環(huán)。
        // 組件接受新的state或者props時(shí)調(diào)用,我們可以設(shè)置在此對(duì)比前后兩個(gè)props和state是否相同,
        // 如果相同則返回false阻止更新,因?yàn)橄嗤膶傩誀顟B(tài)一定會(huì)生成相同的dom樹,
        // 這樣就不需要?jiǎng)?chuàng)造新的dom樹和舊的dom樹進(jìn)行diff算法對(duì)比,節(jié)省大量性能,尤其是在dom結(jié)構(gòu)復(fù)雜的時(shí)候。
    },
    componentWillUpdate (nextProps, nextState) {
        // 組件初始化時(shí)不調(diào)用,只有在組件發(fā)生更新需要重新渲染時(shí)才調(diào)用
    },
    componentDidUpdate (prevProps, prevState) {
        // 組件初始化時(shí)不調(diào)用,組件更新渲染完成后調(diào)用,此時(shí)dom節(jié)點(diǎn)加載完成,可以獲取到dom節(jié)點(diǎn)。
        // react只會(huì)在第一次初始化成功會(huì)進(jìn)入componentDidmount,
        // 之后每次重新渲染后都會(huì)進(jìn)入這個(gè)生命周期,這里可以拿到prevProps和prevState,即更新前的props和state。
        // 該鉤子內(nèi)setState有可能會(huì)觸發(fā)重復(fù)渲染,需要謹(jǐn)慎判斷,否則會(huì)進(jìn)入死循環(huán) 
    },
    render () {
        return (
            <div>This is Demo!</div>
        );
    },
    componentWillUnmount () {
        // 組件將要卸載時(shí)調(diào)用,一些事件監(jiān)聽和定時(shí)器需要在此時(shí)清除。
    },
    componentDidCatch (error, info) {
        //React 16 中引入,用來(lái) 捕獲組件的錯(cuò)誤。
        //如果 render() 函數(shù)拋出錯(cuò)誤,則會(huì)觸發(fā)該函數(shù)。
        //錯(cuò)誤在渲染階段中被捕獲,但在事件處理程序中不會(huì)被捕獲。
    }
}

我們應(yīng)當(dāng)將AJAX 請(qǐng)求放到 componentDidMount 函數(shù)中執(zhí)行,主要原因有下:

React 可能會(huì)多次頻繁調(diào)用 componentWillMount,如果我們將 AJAX 請(qǐng)求放到 componentWillMount 函數(shù)中,那么顯而易見其會(huì)被觸發(fā)多次,自然也就不是好的選擇。

如果我們將 AJAX 請(qǐng)求放置在生命周期的其他函數(shù)中,我們并不能保證請(qǐng)求僅在組件掛載完畢后才會(huì)要求響應(yīng)。如果我們的數(shù)據(jù)請(qǐng)求在組件掛載之前就完成,并且調(diào)用了setState函數(shù)將數(shù)據(jù)添加到組件狀態(tài)中,對(duì)于未掛載的組件則會(huì)報(bào)錯(cuò)。而在 componentDidMount 函數(shù)中進(jìn)行 AJAX 請(qǐng)求則能有效避免這個(gè)問(wèn)題。

componentDidMount() {
    this.getMovie();
}
getMovie(){
    fetch("http://www.endata.com.cn/API/GetData.ashx",{
        method:"post",
        body:"MethodName=BoxOffice_GetPcHomeList",
        headers:{"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
    })
    .then(res=>res.json())
    .then(res=>{
        console.log(res)
    })
}


子組件調(diào)用父組件方法|向父組件傳遞參數(shù)

父親傳一個(gè)函數(shù)props

import React, { Component } from 'react';
import Child from './components/Child'
class App extends Component {  
  showMsg(msg){
    alert(msg);
  }
  render() {  
    return (
      <div className="App">
        <Child name="曾慶林" fun={this.showMsg}></Child>
      </div>
    );
  }
}

export default App;

子組件在箭頭函數(shù)執(zhí)行props

import React,{Component} from 'react' export default class Child extends Component{

render(){
        return (
            <div className="child">
                    <h1>我是子組件 我的名字是{this.props.name}</h1>
                    <button onClick={()=>{this.props.fun('我愛我的祖國(guó)')}}>調(diào)用父親函數(shù)方法</button>                   
                    <hr/>
            </div>
        );
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容