十道前端面試題第【07】篇

1、字節跳動三面之React面試

  • 什麼是虛擬DOM?
  • 類組件和函數組件之間有什麼區別?
  • React中的refs作用是什麼?
  • 在React中如何處理事件
  • 什麼是受控組件?
  • 爲什麼不直接更新state狀態?
  • 描述Flux與MVC?
  • React context是什麼?
  • React Fiber是什麼?


2、描述 Diff運算過程,如何比較兩個虛擬DOM的差異?

  • React官方對 Diff運算過程的說明 :本文描述了在實現 React 的 “diffing” 算法過程中所作出的設計決策,以保證組件更新可預測,且在繁雜業務場景下依然保持應用的高性能。


3、僞代碼封裝 react-redux 庫的connect函數

export default function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
  return function wrapWithConnect(WrappedComponent) {
    class Connect extends Component {
      constructor(props, context) {
        // 從祖先Component處獲得store
        this.store = props.store || context.store
        this.stateProps = computeStateProps(this.store, props)
        this.dispatchProps = computeDispatchProps(this.store, props)
        this.state = { storeState: null }
        // 對stateProps、dispatchProps、parentProps進行合併
        this.updateState()
      }
      shouldComponentUpdate(nextProps, nextState) {
        // 進行判斷,當數據發生改變時,Component重新渲染
        if (propsChanged || mapStateProducedChange || dispatchPropsChanged) {
          this.updateState(nextProps)
            return true
          }
        }
        componentDidMount() {
          // 改變Component的state
          this.store.subscribe(() = {
            this.setState({
              storeState: this.store.getState()
            })
          })
        }
        render() {
          // 生成包裹組件Connect
          return (
            <WrappedComponent {...this.nextState} />
          )
        }
      }
      Connect.contextTypes = {
        store: storeShape
      }
      return Connect;
    }
}


4、從React的角度,有哪些性能優化的策略。

類組件中的優化手段:

  • 使用純組件 PureComponent 作爲基類。
  • 使用 shouldComponentUpdate 生命週期函數來自定義渲染邏輯。

函數式組件中的優化手段:

  • 使用 React.memo 高階函數包裝組件,React.memo 可以實現類似於 shouldComponentUpdate 或者PureComponent 的效果
  • 使用 useMemo 精細化的管控,useMemo 控制的則是是否需要重複執行某一段邏輯,而React.memo 控制是否需要重渲染一個組件
  • 使用 useCallBack

其他方式:

  • 在列表需要頻繁變動時,使用唯一 id 作爲 key,而不是數組下標。
  • 必要時通過改變 CSS 樣式隱藏顯示組件,而不是通過條件判斷顯示隱藏組件。
  • 使用 Suspense 和 lazy 進行懶加載


5、有哪些定義React組件的方式

# 函數式組件
const PureComponent = (props) => (
    <div>
        //use props
    </div>
)
# 類組件
class StatefulComponent extends Component {
    constructor(props) {
        super(props);
        this.state = { }
    }
    render() {
        return ();
    }
}
# 容器組件
var UserListContainer = React.createClass({
  getInitialState: function() {
    return {
      users: []
    }
  },
  render: function() {
    return (<UserList users={this.state.users} />);
  }
})
# 高階組件
const HigherOrderComponent = (WrappedComponent) => {
  return class WrapperComponent extends Component {
    render() {
      <WrappedComponent />
    }
  }
}
# Render Callback組件
class RenderCallbackCmp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: "hello"
    };
  }

  render() {
    return this.props.children(this.state.msg);
  }
}

const ParentComponent = () =>(
  <RenderCallbackCmp>
    {msg =><div>{msg}</div>}
  </RenderCallbackCmp>
)


6、React中組件間通信,有哪些辦法?

  • 父子組件通信
  • 自定義事件
  • 使用 context 上下文
  • 使用 redux 狀態管理


7、談一談 React Hooks API

什麼Hooks?Hooks有什麼用?常用的Hooks有哪些?

  • React官方之 Hooks簡介
  • useCallback 和 useMemo 類似計算屬性的功能,它們只是語法不同而已。
  • useRef 模擬使用 Refs特性。
  • 自定義Hooks是基於useState/useEffect/useContext的封裝
  • 自定義Hooks是一種邏輯複用的策略
  • 自定義Hooks的命名,必須以 use 開頭。

自定義 useTitle 改變文檔頁面的 title

import { useEffect } from 'react'

const useTitle = (title) => {
    useEffect(() => {
      document.title = title
    }, [])
    return
}
export default useTitle

封裝 useReducer 使用 Redux狀態管理工具

function useReducer(reducer, initialState) {
  const [state, setState] = useState(initialState);
  function dispatch(action) {
    const nextState = reducer(state, action);
    setState(nextState);
  }
  return [state, dispatch];
}

// 使用 useReducer
function Todos() {
  const [todos, dispatch] = useReducer(todosReducer, [])
  function handleAddClick(text) {
    dispatch({ type: 'add', text })
  }
}

社區裏面還有很多好用的自定義Hooks

使用上下文和自定義Hooks實現國際化

import React, { useContext } from 'react'
const LangContext = React.createContext()

export function useLang() {
    return useContext(LangContext)
}
export const LangProvider = LangContext.Provider
# App.jsx
<LangProvider value={qfLang}>
  <Layout />
</LangProvider>


8、React技術棧中,有哪些代碼複用的技巧?


9、高階組件有哪些應用場景?

高階組件 不是組件,是 一個把某個組件轉換成另一個組件的 函數。高階組件的主要作用是 代碼複用。高階組件是 裝飾器模式在 React 中的實現。


10、React路由相關

React-Router官方文檔

  • 路由的查詢參數和動態路由,有什麼區別?
  • withRouter 有什麼用?
  • 路由之代碼分割的原理是什麼?如何實現路由代碼分割?
  • 常用的路由 Hooks 有哪些?
  • 路由如何實現鑑權驗證?
  • 對比 vue-router 和 react-router-dom 在概念上有哪些異同?


本週結束,下週繼續!!!

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