美文网首页
十道前端面试题第【07】篇

十道前端面试题第【07】篇

作者: 夏海峰 | 来源:发表于2021-05-19 00:28 被阅读0次

    1、字节跳动三面之React面试

    • 什么是虚拟DOM?
    • 类组件和函数组件之间有什么区别?
    • React中的refs作用是什么?
    • 在React中如何处理事件
    • 什么是受控组件?
    • 为什么不直接更新state状态?
    • 描述Flux与MVC?
    • React context是什么?
    • React Fiber是什么?

    2、描述 Diff运算过程,如何比较两个虚拟DOM的差异?

    • React官方对 Diff运算过程的说明 :本文描述了在实现 React 的 “diffing” 算法过程中所作出的设计决策,以保证组件更新可预测,且在繁杂业务场景下依然保持应用的高性能。
    Diff运算

    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 在概念上有哪些异同?

    本周结束,下周继续!!!

    相关文章

      网友评论

          本文标题:十道前端面试题第【07】篇

          本文链接:https://www.haomeiwen.com/subject/mpkujltx.html