關於React的幾個簡單問題

1.什麼是虛擬DOM

虛擬DOM(VDOM)是真實DOM的內存表示。將整個UI結構保持在內存中並和真正的DOM結構保持同步。在調用渲染函數和元素展示在屏幕上之間有一個處理過程,這個過程叫作reconciliationjavascript

2.虛擬DOM是如何工做的

虛擬DOM的工做過程分爲三個階段:
1)每當任意一個底層數據發生更改時,整個UI都將在虛擬DOM表示中從新渲染
2)對比固然的虛擬DOM和上一份虛擬DOM的不一樣之處
3)對比結束以後,真是DOM就會根據對比結果從新渲染變化的DOM節點java

3.影子(Shadow)DOM和虛擬DOM有什麼區別

Shadow DOM 在網絡平臺中引入做用域樣式。 無需工具或命名約定,您便可使用原生 JavaScript 捆綁 CSS 和標記、隱藏實現詳情以及編寫獨立的組件。
Shadow DOM 與普通 DOM 相同,但有兩點區別:1) 建立/使用的方式;2) 與頁面其餘部分有關的行爲方式。 一般,您建立 DOM 節點並將其附加至其餘元素做爲子項。 藉助於 shadow DOM,您能夠建立做用域 DOM 樹,該 DOM 樹附加至該元素上,但與其自身真正的子項分離開來。這一做用域子樹稱爲影子樹。被附着的元素稱爲影子宿主。 您在影子中添加的任何項均將成爲宿主元素的本地項,包括 <style>。 這就是 shadow DOM 實現 CSS 樣式做用域的方式。
因此,Shadow DOM是一種瀏覽器技術,主要用於在web組件中肯定變量和CSS的範圍。虛擬DOM是一個由JavaScript中的庫在瀏覽器api之上實現的概念。react

4.類組件和方法組件的區別

  • 類組件:它容許您使用其餘特性,如本地狀態和生命週期鉤子。此外,還可使組件直接訪問store,從而保持狀態。
  • 若是你的組件只接收props屬性並將它處理以後渲染在頁面上,那麼這就是個無狀態組件,可使用純函數來實現。

5.refs在React中用於什麼

你可使用refs直接訪問一個元素節點或者組件實例。要使用這個屬性,您須要向組件添加一個ref屬性,該屬性的值是一個回調函數,它將接收底層DOM元素或組件實例做爲其第一個參數。webpack

class UnControlledForm extends Component {
  handleSubmit = () => {
    console.log("Input Value: "this.input.value)
  }
  render () {
    return (
      <form onSubmit={this.handleSubmit}>
        <input
          type='text'
          ref={(input) =>
 this.input = input} />
        <button type='submit'>Submit</button>
      </form>
    )
  }
}
複製代碼

能夠看到,在input標籤上有一個ref屬性,給它賦值了一個函數方法。這個方法接收了input的真實DOM元素,接着咱們將在handleSubmit方法裏面訪問它。
一般認爲只能在類組件中使用refs,但你也但是利用閉包在方法組件中使用。web

function CustomForm ({handleSubmit}{
  let inputElement
  return (
    <form onSubmit={() => handleSubmit(inputElement.value)}>
      <input
        type='text'
        ref={(input) =>
 inputElement = input} />
      <button type='submit'>Submit</button>
    </form>
  )
}
複製代碼

還有另一種使用refs的方法。你能夠用React.createRef()方法建立refs並經過ref屬性綁定到元素上。爲了在整個組件中使用ref,只需將ref分配給構造函數中的實例屬性。編程

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.myRef = React.createRef()
  }
  render() {
    return <div ref={this.myRef} />
  }
}
複製代碼

6.什麼是forward refs

Ref forwarding 是一個性質,它容許組件接收一個ref屬性,並將這個屬性傳遞給子組件。api

const ButtonElement = React.forwardRef((props, ref) => (
  <button ref={ref} className="CustomButton">
    {props.children}
  </button>

));

// Create ref to the DOM button:
const ref = React.createRef();
<ButtonElement ref={ref}>{'Forward Ref'}</ButtonElement>
複製代碼

7.描述一下React中事件是怎麼處理的

爲了解決跨瀏覽器兼容性問題,React中的事件處理中將傳遞SyntheticEvent的實例,SyntheticEvent是React中包裝了各類瀏覽器原生屬性的跨瀏覽器包裝器。它暴露出統一的事件接口,保證在不一樣瀏覽器上都可以正常運行。
稍微有趣的是,React實際上並無將事件附加到子節點自己。而是使用事件代理的方式,React使用一個事件偵聽器在頂層偵聽全部事件。這有助於提升性能,也意味着React在更新DOM時沒必要擔憂跟蹤事件偵聽器被移除。數組

8.state和props之間有什麼不一樣

props和state都是純JavaScript對象。雖然它們都包含影響渲染輸出的信息,但它們在組件方面的功能不一樣。好比:瀏覽器

  • props將數據傳遞給組件,功能相似於函數中的參數
  • state則維護在組件內部,相似於函數中定義的變量

9.什麼是高階組件

高階組件(HOC)就是一個方法,它接收一個組件並返回一個新的組件。這是一種由React的組成性質衍生出來的模式。
也能夠成爲「純組件」,由於它們能夠接受任何動態提供的子組件,但不會修改或複製其輸入組件中的任何行爲。
HOC 能夠用在不少狀況下,好比:網絡

  • 代碼重用、邏輯和引導抽象
  • 狀態抽象與操做
  • Props操做

10.使用帶有props參數的超級構造函數的目的是什麼

一個子類的構造器在調用sper方法以前是不能使用this引用的。就行ES6中的sub-classes。將props參數傳遞給super()調用的主要緣由是訪問子構造函數中的this.props。

  • 傳遞props
class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        console.log(this.props);  // Prints { name: 'sudheer',age: 30 }
    }
}
複製代碼
  • 不傳遞props
class MyComponent extends React.Component {
    constructor(props) {
        super();
        console.log(this.props); // Prints undefined
        // But Props parameter is still available
        console.log(props); // Prints { name: 'sudheer',age: 30 }
    }

    render() {
        // No difference outside constructor
        console.log(this.props) // Prints { name: 'sudheer',age: 30 }
    }
}
複製代碼

上面的代碼片斷能夠看出,this.props行爲僅在構造函數中不一樣,構造函數以外的表現都是同樣的。

11.什麼是受控組件

在HTML中,表單元素<input><select>以及<textarea>等,都維護本身的狀態並根據用戶輸入進行更新。當用戶提交表單時,上述元素的值將隨表單一塊兒發送。但在React中,並非這樣的,包含表單的組件將跟蹤處於其狀態中的<input>的值,並在每次啓動回調函數(例如onChange)時,由於狀態將被更新而從新渲染該組件。
一個輸入表單元素,其值以這種方式由React控制,稱爲受控組件。

12.下面的表達式使用React.createElement的等價寫法

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>

);
複製代碼

Answer:

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);
複製代碼

13.怎麼理解JSX

當facebook第一次向人們介紹react時,也介紹了一種新的JavaScript寫法,也就是 JSX,它將HTML模版寫在javascrit代碼中。JSX自己是沒法被瀏覽器識別的,它必須藉助bable或者webpack編譯成傳統的javascrit。儘管解一開始許多開發人員下意識的反對這種寫法,但JSX(與ES2015一塊兒)已經成爲定義React組件的肯定方法。

class MyComponent extends React.Component {
  render() {
    let props = this.props;  
    return (
      <div className="my-component">
      <a href={props.url}>{props.name}</a>
      </div>

    );
  }
}
複製代碼
14.給定一段代碼,找出其中的兩處問題?

代碼以下:

class MyComponent extends React.Component {
  constructor(props) {
    // set the default internal state
    this.state = {
      clicks: 0
    };
  }

  componentDidMount() {
    this.refs.myComponentDiv.addEventListener('click'this.clickHandler);
  }

  componentWillUnmount() {
    this.refs.myComponentDiv.removeEventListener('click'this.clickHandler);
  }

  clickHandler() {
    this.setState({
      clicks: this.clicks + 1
    });
  }

  render() {
    let children = this.props.children;

    return (
      <div className="my-component" ref="myComponentDiv">
      <h2>My Component ({this.state.clicks} clicks})</h2>
      <h3>{this.props.headerText}</h3>
    {children}
    </div>
    );
  }
}
複製代碼

Answer:

  • 構造器中沒有將props傳給supr()
constructor(props) {
  super(props);
  // ...
}

複製代碼
  • 事件偵聽器(經過addEventListener()分配時)的做用域不正確。所以,開發人員須要在構造函數中從新分配clickHandler,以包含對此的正確綁定:
constructor(props) {
  super(props);
  this.clickHandler = this.clickHandler.bind(this);
  // ...
}

複製代碼

15.介紹下React組件生命週期的不一樣階段

React組件的生命週期有四個不一樣的階段:

  1. 初始化(Initialization):在此階段,react組件準備設置初始狀態和默認props。
  2. mounting這個階段包括componentWillMountcomponentDidMount**兩個生命週期方法。
  3. 更新(updating):在這個階段,組件經過兩種方法獲取更新:傳入新的props以及更新state。包括shouldComponentUpdate, componentWillUpdate 以及 componentDidUpdate三個生命週期方法。
  4. Unmounting: 最後一個階段,組件再也不被須要,就會從DOM節點上移除。包括componentWillUnmount方法。

16.React中的生命週期方法

  1. componentWillMount:在渲染以前觸發,能夠用來在根組件裏作APP級別的配置。
  2. componentDidMount:在渲染以後觸發,在這個階段AJAX請求、DOM和狀態更新以及事件監聽均可以觸發了。
  3. componentWillReceiveProps:在特定的prop更新引發state變化時觸發。
  4. shouldComponentUpdate:用來決定組件是否應該被更新。一般默認返回true。若是你確認組件在state或者prop變化以後不須要更新,那麼你能夠返回false。由於你能夠在組件接收到一個新的prop的時候阻止組件的從新渲染,這對於提升組件性能是一種很好的方式。
  5. componentWillUpdate:props或者state發生變化以及shouldComponentUpdate返回爲true,那麼在組件從新渲染以前就會觸發此方法。
  6. componentDidUpdate:它主要用於更新DOM以響應prop或state的更改。
  7. componentWillUnmount:這個方法主要用於取消任何已發出的網絡請求,或刪除與組件關聯的全部事件偵聽器。

17.什麼是React Hooks

React Hooks時在React 16.8新增的性質。它的的意思是,組件儘可能寫成純函數,若是須要外部功能和反作用,就用鉤子把外部代碼"鉤"進來。
它容許你不須要寫一個類,就可使用react的狀態和其它性質。經過Hooks,您能夠從組件中提取有狀態邏輯,這樣就能夠獨立測試並重用它。Hooks容許您重用有狀態邏輯,而無需更改組件層次結構。這使得在許多組件之間鉤子變得很容易。

18.使用React Hooks有什麼優點

在Hooks出現以前,咱們寫一個簡單的組件都要建立一個類,在大型複雜的項目中每每很複雜。最終致使:

  • 大型組件很難拆分和重構,也很難測試。
  • 業務邏輯分散在組件的各個方法之中,致使重複邏輯或關聯邏輯。
  • 組件類引入了複雜的編程模式,好比 render props 和高階組件。

React Hooks 的設計目的,就是增強版函數組件,徹底不使用"類",就能寫出一個全功能的組件。
一般, hooks可以提取和重用狀態邏輯,這種邏輯在多個組件之間是通用的,而不須要高階組件或渲染props來實現。hooks可以輕鬆地操做功能組件的狀態,而無需將它們轉換爲類組件。
Hooks在類組件裏面不起做用。經過使用它,咱們能夠避免使用componentDidMount, componentDidUpdate, componentWillUnmount這些生命週期方法。但須要使用例如useffect這樣的內置鉤子。

19.React中useState()是什麼

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};
複製代碼

useState是react hooks的一個內置方法。useState(0)返回一個元組,其中第一個參數count是計數器的當前狀態,setCounter是容許咱們更新計數器狀態的方法。
咱們可使用setCounter方法在任何地方更新count的狀態。這裏,咱們在setCount函數中使用它,在這裏咱們能夠作更多的事情;hooks的思想是,咱們可使代碼更具功能性,並在非必要的狀況下避免基於類的組件。

20.描述一下Flux vs MVC

傳統的MVC框架很好的將數據 (Model), UI (View) 以及 邏輯 (Controller) 分離開,但它仍然面臨兩個問題:

  • 數據流的弱定義:在視圖之間發生的層疊更新經常致使難以調試的復瑣事件網絡。
  • 缺乏數據的總體管理:模型數據能夠從任何地方變異,從而在整個UI中產生不可預測的結果。

Flux模式使得複雜組件不須要再經過級聯更新的方式渲染組件。每一個組件均可以經過store提供的數據維護本身的狀態。Flux模式還經過限制對共享數據的直接訪問來加強數據的統一管理。

相關文章
相關標籤/搜索