react從零到一

啦啦啦,今天開始就要正式開始個人react之路了,首先我用了create-react-app命令工具快速建了一個react項目,既然是從0到1,我就給src裏面的內容刪的乾乾淨淨。 寫了一個最簡單的:html

//index.js
// 導入的React必須大寫
import React from 'react';
import ReactDom from 'react-dom';
const h1 = <h1>hello world</h1>;  //會用babel進行轉化 轉化成React.createElement寫法
// 是語法糖

ReactDom.render(h1,window.root)
複製代碼

問題1: 爲何必須React大寫?vue

問題2: reader咋實現的?node

先來講問題一: 原來啊 jsx語法配合babel編譯 而後調用React.createElement 那就本身寫一個吧react

let React = {
  createElement(type,props,...children){
    return {
      type,props,children
    }
  }
}

複製代碼

問題2:render實現面試

// 固然這個render方法只是描述render最終幹嗎了,實際在render中要遠比這複雜,涉及到dom diff
let render = (vnode,container) => {
    if(typeof vnode == 'string') return container.appendChild(document.createTextNode(vnode));
    
    let {type,props,children} = vnode;
    let ele = document.createElement(type);
    for(let key in props) {
        ele.setAttribut(key,props[key]);
    }
    children.forEach((child)=>{
        render(child,ele)
    })
    container.appendChild(ele);
}
複製代碼

接下來咱們稍微複雜一點 渲染多個元素: 須要注意的是多個元素須要被一個標籤包裹起來,我通常是數組

let ele = (
    <> <h1>你好</h1> <span>哈哈</span> </> ) 複製代碼

上面只是簡單的介紹,那jsx語法有如下這些規則:babel

  1. jsx 是能夠包含js的語法 與html的寫法是有一些區別的
  1. 若是渲染兩個相鄰的jsx元素 須要被外面的一個標籤所包裹 <></>app

  2. 行內樣式的寫法, jsx爲了識別是html仍是js 須要用 < { 來區分dom

  3. {} 表示的是寫js 三元表達式,取值 ,(只要內容有返回值就能夠顯示)函數

  4. 屬性的名字有變化 htmlFor => for / className=> class;

  5. 像v-html 把內容當成html 插入到頁面中 dangerouslySetInnerHTML

  6. 註釋只能寫js註釋

{/*當前是一個危險的操做 */}
<div dangerouslySetInnerHTML={{__html:str}}></div>
複製代碼
  1. 列表渲染 map 數組是能夠直接渲染的(沒必要須被包裹一個標籤)
let arr = ['吃飯', '喝水', '睡覺']
let eleArr = arr.map((item) => {
   <li>{item}</li> 
})
ReactDOM.render(eleArr,window.root)  
複製代碼
  1. 嵌套
let arr = ['吃飯', '喝水', '睡覺']
let eleArr = arr.map((item) => {
   <li>{item}</li> 
})
let obj = (
   <ul>
       {eleArr}
   </ul>
)
複製代碼

以上就是jsx的基本用法,可是一個項目會很複雜,咱們經常會封裝不少組件,這樣便於複用和維護,人家react文檔中說了,在react中,一個函數就是一個組件。

在react中 組件名必須大寫,和jsx,react元素進行區分

import React from 'react';
import ReactDom from 'react-dom';
function Clock() {
   return (<h1>當前時間</h1>)
}

ReactDom.render(<Clock></Clock>,window.root)
//或者這樣 還能夠和jsx嵌套
//ReactDom.render(<div><Clock></Clock></div>,window.root)
複製代碼

其實在react中有兩類組件: 全部組件都有屬性

  1. 就是上面的函數組件
  • 沒有this指向;
  • 沒有生命週期;
  • 沒有狀態

函數組件屬性的用法:

function Clock(props) {
   return (<h1>當前時間:props.date.toLocaleString()</h1>)
}

ReactDom.render(<Clock date={new Date()}></Clock>,window.root)
複製代碼
  1. 類組件 類組件解決以上幾個問題 this指向 生命週期 狀態
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父類 提供更改狀態的 setState方法
class Clock extends Component{
   <!--constructor(props) {-->
   <!-- super(props) //Component.call(this,props)--> <!-- this.state = {}--> <!--}--> state = { //es7 date: new Date().toLocaleString() } render(){ return <h1>時間是:{this.state.date}</h1> } } ReactDom.render(<Clock></Clock>,window.root) 複製代碼

接下來咱們瞭解一個很是重要的概念 生命週期 和vue同樣 像上面的時鐘案例,咱們須要讓時鐘走動,最low的方法就是不斷的render,也有用更改狀態setState方法,可是何時去執行呢,這裏就涉及到生命週期的問題了

  • componentWillMount 組件即將掛載
  • componentDidMount 組件已經掛載
  • componentWillReceiveProps 在接受父組件改變後的props須要從新渲染組件時,父親render時 兒子必會render
  • shouldComponentUpdate 惟一用於控制組件從新渲染的生命週期,在這裏return false能夠阻止組件的更新
  • componentWillUpdate 組件即將更新
  • componentDidUpdate 組件已經更新
  • componentWillUnmount 組件即將卸載 那咱們寫了這麼多彷佛還缺乏與用戶的交互環節,例如用戶點擊觸發了啥啥啥,就是綁定事件怎麼綁,在react中綁定事件的方法名都是駝峯寫法,還以上個例子爲例:
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父類 提供更改狀態的 setState方法
class Clock extends Component{
   state = {   //es7
       date: new Date().toLocaleString()
   }  
   handleClick = () => {   //妥善處理好了this指向問題
       console.log(this)
   } 
   componentDidMount() {
       setInterval(() => {
           this.setState({   //只會改動你要改動的,並不會幹掉你沒有要改動的
               date: new Date().toLocaleString()
           })
       },1000)
   }   
   render(){
       return <h1>時間是:{this.state.date} <span onClick={this.handleClick}>點擊</span></h1> 
   }
}
ReactDom.render(<Clock></Clock>,window.root)
複製代碼

這裏留一個經典面試題: setState 批量更新 只針對同一個屬性變量 不一樣的屬性變量沒有這個問題

解決方法:

1)setTimeout() 不推薦 2)prevState

this.setState((prevState) => {
   count: prevState.count+1
})

//等價下面
this.setState({
   count:this.state.count+1
},() => {
   <!--在下一個state操做-->
})
複製代碼

總結一下:

  1. import React, {Component} from 'react'
import React, {Component} from 'react';
import ReactDom from 'react-dom'

class Count extends Component{
   constructor() {
       super()
   }
   state = {
       
   }
   
   render(){
       return (
           <div> </div>
       )
   }
}

ReactDom.render(<Count></Count>,window.root)
複製代碼
  1. import ReactDom from 'react'
  2. jsx語法 屬性名變化 htmlFor -> for class -> className,列表渲染 Map,組件名必須大寫,函數組件, 給元素綁定事件(事件名駝峯寫法)(this指向問題注意)以及生命週期
{this.props.xxx}
{this.state.xxx}
複製代碼
  1. 屬性和狀態 屬性不可更改 狀態能夠改可是必須是setState的方式 批量更新的問題: prevState或者回調函數方式

以上是本身學習入門React的入門筆記,分享給你們,固然還有不少不足之處但願你們指出,我會繼續再接再礪更深刻的從一到二

相關文章
相關標籤/搜索