react面试精讲

作者: 戈德斯文 | 来源:发表于2019-01-14 11:54 被阅读186次
    1. redux中间件的原理是什么?答:改装dispatch。是action到store中间,所以叫中间件。
    fucntion createThunkMiddleware(extraArgument) {
        return ({ dispatch, getState }) => next => action => {
            if (typeof action === 'function') {
                return action(dispatch, getState, extraArgument);
            }
            
            return next(action)
        };
    }
    
    const thunk = createThunkMiddleware();
    thunk.withExtraArgument = createThunkMiddleware;
    
    export default thunk;
    
    1. 你会把数据统一放到redux中管理,还是共享数据放在redux中管理?答:不是react native,所有数据都要放在redux中管理。如果只是把共用的数据放在redux中,一个组件中会既有state、props和redux存储数据,那么当页面出现问题,要从state、props和redux三个方面检查,开发程序是很快的,但是最费时间的是程序后期的可维护性和代码的可调节性。如果数据都放在redux中管理,项目出错以后,就只用检查redux,定位错位很快。不要想着state中的数据只会供一个组件使用,在项目越来越大的时候,说不准别的组件会需要使用。redux中可以存储5GB的数据(Dell老师做过测试)。所以,能用redux的时候一定要用redux,对于后期的维护来说很方便。immutable,当你把redux和immutable这个库结合使用的时候,你整个项目的性能会达到最优,而且非常非常简单。没有数据臃肿的顾虑,你不存在redux中,你也需要存储在state或者props中。
    2. componentWillReceiveProps的调用时机。答:props改变的时候才会调用,父组件第一次往子组件传值的时候,不会调用。
    3. react性能优化的最佳实践。答:PureComponent,自带shouldcomponentupdate,是一个浅比较。
    class Test extends React.PureComponents {
        constructor(props) {
            super(props)
        }
        
        render() {
            return <div>hello</div>
        }
    }
    

    通过与immutable.js库的结合,完美的解决react的性能问题,非常的完美。

    1. 虚拟dom是什么?为什么虚拟dom会提升代码性能。答:js对象,为什么现在都用虚拟dom,虚拟dom就是真实dom的一个js对象。以前需要两个页面的差异,需要去比对真实dom的比对,真实的dom节点会有事件,属性,还会有各种各样的方法。所以两个真实dom的比对会非常耗性能。于是把dom对象变成js对象,js对象就没有dom对象上乱七八糟的特性了。js对象就比较快。
    2. webpack中,借助loader完成的JSX代码的转化,还是babel?答:babel - preset-react,
    3. 调用setState后,发生了什么?答:调和作用
    this.setState({
        age: this.state.age + 1
    }) // 如果是连续点击一个按钮调用这个setState,会出现数值不是一个一个加上去的,而是会出现一次几个的变化,因为react会把多个setState整合为一个,最后在改变state。
    
    this.setState((prevState) => ({
        age: ++ prevState.age
    })) // 不管你怎么疯狂的点击按钮,都会一个一个往上加。
    

    推荐使用setState的时候返回传一个函数

    1. setState是异步的,这个点你在什么时候遇到过坑。答:同上。
    2. refs的作用是什么,你在什么业务场景下使用过refs。答:获取图片的宽高等。
    class Test extends Component {
        // 需求:当页面滚动,监听页面滚动的事件
        constructor(props) {
            super(props);
            this.state = {
                top: 0
            }
        }
        
        componentDidMount() {
            window.addEventListener('scroll', () => {
                this.setState(() => ({
                    top: document.body.scrollTop
                }))
            })
        }
        
        render() {
            return <div>{this.state.top}</div>
        }
    }
    

    上面这种写法,在组件销毁的时候,scroll事件依然存在

    class Test extends Component {
        // 需求:当页面滚动,监听页面滚动的事件
        constructor(props) {
            super(props);
            this.state = {
                top: 0
            }
            this.handleWindowScroll = this.handleWindowScroll.bind(this)
        }
        
        handleWindowScroll() {
            this.setState(() => ({
                top: document.body.scrollTop
            }))
        }
        
        componentDidMount() {
            window.addEventListener('scroll', this.handleWindowScroll)
        }
        
        componentWillUnmount() {
            window.removeEventListener('scroll', this.handleWindowScroll)
        }
        
        render() {
            return <div>{this.state.top}</div>
        }
    }
    
    1. ref是一个函数,有什么好处?
      好处:方便react在销毁或者重新渲染组件的时候去有效的去清空ref里面的东西,防止内存泄漏,以后ref不要用字符串的形式了,很low,要用函数式的写法
    class Test extends Component {
      componentDidMount() {
        this.elem
      }
    
      render() {
        return <div ref={(div) => { this.elem = div }}></div> // ref使用的时候最好使用函数
      }
    }
    
    1. 高阶组件你是怎么理解的,它的本质是一个什么东西?
      在react里面不要去使用继承,为什么,设计模式中有这样一句话“组合优于继承”,react这种组件式的编程,是一种组合类型的设计模式,一定是优于继承的,可维护性是比继承高的多,react中所有问题都是可以利用组件拼合的方法解决的。
      高阶组件实际上就是一个函数,接收参数,返回参数。对一个组件进行包装,然后再返回一个组件。为什么对一个组件进行包装呢,因为组件有可能很多地方要用,这个组件的大部分东西在别的地方都可以直接用,只有少数的地方有区别,我们就可以把共用的地方写到高阶组件里面去,而通过网高阶组件里面传递参数,来去动态这个组件在使用时的差异。
      高阶组件地狱。新版本的hook解决了这个问题。
    <A>
      <B>
        <C>
          <D />
        </C>
      </B>
    </A>
    
    1. 受控组件和非受控组件的区别?
      受控组件:这个组件的改变完全受控于数据的变化,数据变了,页面变了
      非受控组件:input框,我直接操作dom,我不让他进行数据的绑定,输入完成点击按钮的时候,我直接通过refs拿dom上的内容来进行操作,不是通过数据来控制。

    受控组件一定是更好的。react是一个数据驱动的框架,所以数据驱动是react核心,所以组件都应该被数据控制。

    1. 函数组件和hooks?
    2. this指向问题你一般怎么去解决?
      箭头函数,bind,声明变量保存this
      箭头函数this是作用域链的问题。
    3. 函数组件怎么做性能优化。
      函数式组件性能比普通组件性能高,因为函数组件没有类的其他属性,没有构造类的过程。低是因为,函数式组件,props发生变化以后,函数就会重新执行,React.memo(function Test() { return <div>123</div> }),这样包装,组件就会有shoulComponentUpdate这样的属性,这样函数式组件的性能一定要不普通组件的性能要好的。
    function Test() {
      return <div>123</div>
    }
    
    1. 在哪个生命周期里发送ajax?
      一定要在componentDidMount中去发送,第一,componentWillMount在新版本的react中已经被废弃了,取而代之的是一个getDerivedStateFromProps这样一个生命周期函数,所以用componentWillMount不合适,第二,在用ssr项目中的时候,componentWillMount要做服务端数据的获取,所以不能被占用。
    2. ssr的原理是什么?
    3. redux-saga的设计思想是什么?什么是sideEffects?
    1. react, jquery,vue是否有可能共存在一个项目中?
      完全可以共存。关键看怎么共存。

    2. 组件是什么?类是什么?类被编译成什么?
      组件指的是页面的一部分,用类去实现,编译成一个构造函数

    3. 你是如何跟着社区成长的?

    4. 如何避免ajax数据重新获取?
      使用redux,判断数据有没有,有的话就不要再次请求

    5. react-router4的核心思想是什么,和3有什么区别?
      3的路由需要在一个文件内容易配置,而4的理念则是把一个路由当做是一个组件,直接在组件中使用,这是4和3在设计理念上的不同

    6. immutable.js和redux的最佳实践?

    7. reselect是做什么使用的?

    8. react-router的基本原理,hashHistory,browserHistory?
      hashHistory在#,browserHistory看似像简洁,却需要服务端的支持

    9. 什么情况下使用异步组件?
      异步组件,懒加载,按需加载
      如果可以,尽量在所有项目中使用,可以减小项目打包后的大小,在前端加载的时候,不会一次加载过大的js文件

    10. xss攻击在react中如何防范?

    <div dangerouslySetInnerHTML={{ __html: '<script>alert(1)</script>' }}></div>
    

    react直接解析字符串,字符串带有script标签,标签内写有可执行的js代码,
    尽量在创建的时候转义

    1. getDerive的StateFromProps

    相关文章

      网友评论

        本文标题:react面试精讲

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