React常見面試題 ( 二 )

1.Virtual DOM 如何工作?

Virtual DOM 分爲三個簡單的步驟。

  • 每當任何底層數據發生更改時,整個 UI 都將以 Virtual DOM 的形式重新渲染。
    在這裏插入圖片描述
  • 然後計算先前 Virtual DOM 對象和新的 Virtual DOM 對象之間的差異。
    在這裏插入圖片描述
  • 一旦計算完成,真實的 DOM 將只更新實際更改的內容。
    -在這裏插入圖片描述

2.如何發起 AJAX 調用以及應該在哪些組件生命週期方法中進行 AJAX 調用?

你可以使用 AJAX 庫,如 Axios,jQuery AJAX 和瀏覽器內置的 fetch API。你應該在 componentDidMount() 生命週期方法中獲取數據。這樣當獲取到數據的時候,你就可以使用 setState() 方法來更新你的組件。

例如,從 API 中獲取員工列表並設置本地狀態:

class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      employees: [],
      error: null
    }
  }

  componentDidMount() {
    fetch('https://api.example.com/items')
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            employees: result.employees
          })
        },
        (error) => {
          this.setState({ error })
        }
      )
  }

  render() {
    const { error, employees } = this.state
    if (error) {
      return <div>Error: {error.message}</div>;
    } else {
      return (
        <ul>
          {employees.map(item => (
            <li key={employee.name}>
              {employee.name}-{employees.experience}
            </li>
          ))}
        </ul>
      )
    }
  }
}

3.在 React Router v4 中的組件是什麼?

React Router v4 提供了以下三種類型的 組件:

  • < BrowserRouter >
  • < HashRouter >
  • < MemoryRouter >

以上組件將創建browser,hash和memory的 history 實例。React Router v4 通過router對象中的上下文使與您的路由器關聯的history實例的屬性和方法可用。

4.history 中的 push() 和 replace() 方法的目的是什麼?

一個 history 實例有兩種導航方法:

  • push()
  • replace()

如果您將 history 視爲一個訪問位置的數組,則push()將向數組添加一個新位置,replace()將用新的位置替換數組中的當前位置。

5.如何使用在 React Router v4 中以編程的方式進行導航?

在組件中實現操作路由/導航有三種不同的方法。

1.使用withRouter()高階函數:
withRouter()高階函數將注入 history 對象作爲組件的 prop。該對象提供了push()和replace()方法,以避免使用上下文。

import { withRouter } from 'react-router-dom' // this also works with 'react-router-native'

const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    {'Click Me!'}
  </button>
))

2.使用組件和渲染屬性模式:
組件傳遞與withRouter()相同的屬性,因此您將能夠通過 history 屬性訪問到操作歷史記錄的方法。

import { Route } from 'react-router-dom'

const Button = () => (
  <Route render={({ history }) => (
    <button
      type='button'
      onClick={() => { history.push('/new-location') }}
    >
      {'Click Me!'}
    </button>
  )} />
)

3.使用上下文:
建議不要使用此選項,並將其視爲不穩定的API。

const Button = (props, context) => (
  <button
    type='button'
    onClick={() => {
      context.history.push('/new-location')
    }}
  >
    {'Click Me!'}
  </button>
)

Button.contextTypes = {
  history: React.PropTypes.shape({
    push: React.PropTypes.func.isRequired
  })
}

6.爲什麼你會得到 “Router may have only one child element” 警告?

此警告的意思是Router組件下僅能包含一個子節點。

你必須將你的 Route 包裝在塊中,因爲是唯一的,它只提供一個路由。

首先,您需要在導入中添加Switch:

import { Switch, Router, Route } from 'react-router'

然後在塊中定義路由:

<Router>
  <Switch>
    <Route {/* ... */} />
    <Route {/* ... */} />
  </Switch>
</Router>

7.如何在 React Router v4 中將 params 傳遞給 history.push 方法?

在導航時,您可以將 props 傳遞給history對象:

this.props.history.push({
  pathname: '/template',
  search: '?name=sudheer',
  state: { detail: response.data }
})

search屬性用於在push()方法中傳遞查詢參數。

8.如何實現默認頁面或 404 頁面?

< Switch>呈現匹配的第一個孩子。 沒有路徑的總是匹配。所以你只需要簡單地刪除 path 屬性,如下所示:

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/user" component={User}/>
  <Route component={NotFound} />
</Switch>

9.redux中間件

中間件提供第三方插件的模式,自定義攔截 action -> reducer 的過程。變爲 action -> middlewares -> reducer 。這種機制可以讓我們改變數據流,實現如異步 action ,action 過濾,日誌輸出,異常報告等功能
常見的中間件:

  • redux-logger:提供日誌輸出
  • redux-thunk:處理異步操作
  • redux-promise:處理異步操作,actionCreator的返回值是promise

10.redux有什麼缺點

1.一個組件所需要的數據,必須由父組件傳過來,而不能像flux中直接從store取。
2.當一個組件相關數據更新時,即使父組件不需要用到這個組件,父組件還是會重新render,可能會有效率影響,或者需要寫複雜的shouldComponentUpdate進行判斷。

11.react生命週期函數

在此推薦一個博客,關於react生命週期寫的很詳細 【超級吳小迪 react生命週期】

這個問題要考察的是組件的生命週期

一、初始化階段:
getDefaultProps:獲取實例的默認屬性
getInitialState:獲取每個實例的初始化狀態
componentWillMount:組件即將被裝載、渲染到頁面上
render:組件在這裏生成虛擬的DOM節點
componentDidMount:組件真正在被裝載之後

二、運行中狀態:
componentWillReceiveProps:組件將要接收到屬性的時候調用
shouldComponentUpdate:組件接受到新屬性或者新狀態的時候(可以返回false,接收數據後不更新,阻止render調用,後面的函數不會被繼續執行了)
componentWillUpdate:組件即將更新不能修改屬性和狀態
render:組件重新描繪
componentDidUpdate:組件已經更新

三、銷燬階段:
componentWillUnmount:組件即將銷燬

12.react性能優化方案

(1)重寫shouldComponentUpdate來避免不必要的dom操作。
(2)使用 production 版本的react.js。
(3)使用key來幫助React識別列表中所有子組件的最小變化。

13.(在構造函數中)調用 super(props) 的目的是什麼

在 super() 被調用之前,子類是不能使用 this 的,在 ES2015 中,子類必須在 constructor 中調用 super()。傳遞 props 給 super() 的原因則是便於(在子類中)能在 constructor 訪問 this.props

14.應該在 React 組件的何處發起 Ajax 請求

在 React 組件中,應該在 componentDidMount 中發起網絡請求。這個方法會在組件第一次“掛載”(被添加到 DOM)時執行,在組件的生命週期中僅會執行一次更重要的是,你不能保證在組件掛載之前 Ajax 請求已經完成,如果是這樣,也就意味着你將嘗試在一個未掛載的組件上調用 setState,這將不起作用。在 componentDidMount 中發起網絡請求將保證這有一個組件可以更新了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章