当你要配置webpack或babelpresets时,会提示你脱离create-react-app的依赖。React16中新的生命周期有哪些关于React16开始应用的新生命周期:可以看出,React16从上到下在另一个维度解释生命周期:Render阶段:用于计算一些必要的状态信息.这个阶段可能会被React挂起,这与React16引入的Fiber架构有关(后面会重点介绍);预提交阶段:所谓“提交”,这里指的是“更新真实DOM节点”的动作。所谓Pre-commit,就是这个阶段我还没有真正更新真实的DOM,但是DOM信息已经是可读的了;Commit阶段:在这一步,React会完成对真实DOM的更新。在Commit阶段,我们可以获得真正的DOM(包括refs)。同时,在流程上,新的生命周期依然遵循“挂载”、“更新”、“卸载”三大划分。它们分别对应:挂载过程:constructorgetDerivedStateFromPropsrendercomponentDidMount更新过程:getDerivedStateFromPropsshouldComponentUpdaterendergetSnapshotBeforeUpdatecomponentDidUpdate卸载过程:componentWillUnmountReact.forwardRef是什么?它有什么作用?React.forwardRef创建一个React组件,该组件将它接受的refprop转发到其组件树下的另一个组件。这种技术并不常见,但在以下两种场景下特别有用:将refs转发给DOM组件在高阶组件中转发refs为什么虚拟dom会提高性能虚拟dom相当于在js和真实dom之间加了一个缓存,使用domdiff算法避免不必要的dom操作,从而提高性能。具体实现步骤如下:使用JavaScript对象结构来表示DOM树的结构;然后使用这棵树构建一个真正的DOM树并将其插入到文档中;当状态改变时,重建一个新的对象树。然后比较新树和旧树,记录两棵树的不同;将步骤2中记录的差异应用到步骤1中构建的真实DOM树,视图将被更新。vue或者react优化虚拟dom的整体优化。为什么虚拟dom会提高性能?(必填)虚拟dom相当于在js和真实dom之间加了一个缓存,使用domdiff算法避免不必要的dom操作,从而提高性能。使用JavaScript对象结构来表示DOM树的结构;然后用这棵树构建一个真正的DOM树,当状态改变时将它插入到文档中,重建一个新的对象树。然后将新树与旧树进行比较,记录两棵树的差异,将第2步记录的差异应用到第1步构建的真实DOM树上,视图就会更新。componentWillReceiveProps的理解该方法在props改变时执行,而不是在render初始化时执行。在这个回调函数中,你可以根据属性的变化调用this.setState()来更新你的组件状态。旧的属性仍然可以通过this.props获取。在这里调用更新状态是安全的,不会触发额外的渲染调用。好处:在这个生命周期中,可以在子组件的render函数执行之前获取到新的props,从而更新子组件自身的状态。数据请求可以放在这里执行,传递的参数从componentWillReceiveProps(nextProps)中获取。而不是把所有的请求都放在父组件中。那么只有在组件渲染时才会发送请求,从而减轻请求负担。componentWillReceiveProps不会在render初始化时执行,当Component接收到新的状态(Props)时会被触发,一般用于父组件状态更新时子组件的重新渲染。详细答案参考前端进阶面试题。钩子将值从父母传递给孩子。使用useState在父组件中声明数据。const[data,setData]=useState(false)向子组件传递数据child组件接收exportdefaultfunction(props){const{data}=propsconsole.log(data)父传子传父可以通过事件方法传值,有点类似于父传子。在父组件中使用useState声明数据const[data,setData]=useState(false)并将更新数据的函数传递给子组件在子组件中触发函数更新数据组件,会直接传给父组件exportdefaultfunction(props){const{setData}=propssetData(true)}如果有多级数据传输,也可以按照这个方法依次传输//多级使用useContextconstUser=()=>{//不回调直接获取const{user,setUser}=useContext(UserContext);return;};React组件中如何做事件代理?它的原理是什么?React基于VirtualDOM实现了一个SyntheticEvent层(合成事件层)。定义的事件处理器会接收一个合成事件对象的实例,该对象符合W3C标准,与浏览器原生事件具有相同的接口,支持冒泡机制,所有事件自动绑定到最外层。在React底层,对于合成事件主要做了两件事:事件委托:React会将所有的事件绑定到结构的最外层,使用一个统一的事件监听器,它维护一个映射来保存所有组件内部的事件监听和处理功能。自动绑定:在React组件中,每个方法的上下文都会指向组件的实例,即this自动绑定到当前组件。React性能优化是哪个周期函数shouldComponentUpdate这个方法用来判断是否需要调用render方法重绘dom。因为dom的渲染是非常耗性能的,如果我们能在shouldComponentUpdate方法中写一个更优化的domdiff算法,性能可以大大提升如何告诉React应该编译生产环境版本通常我们会使用DefinePluginWebpack的方法将NODE_ENV变量值设置为生产。在编译版本中,React会忽略propType验证等警告信息,同时也会减少代码库的大小。React使用Uglify插件去除生产环境中不需要的注释等信息。什么是还原?Redux的基本思想是将整个应用程序的状态保存在一个单独的store中。store只是一个javascript对象,改变应用程序状态的唯一方法是在应用程序中触发动作,然后为这些动作编写reducer来修改状态。整个状态转换在reducer中完成,不应该有任何副作用。这段代码有什么问题?类App扩展组件{constructor(props){super(props);this.state={username:"友家前端网络",msg:"",};}render(){return
{this.state.消息
;}componentDidMount(){this.setState((oldState,props)=>{return{msg:oldState.username+"-"+props.intro,};});}}render(
,ickt)页面正常输出“优客前端网-前端技术专业学习平台”。但是这种写法很少用到,也不是常用的写法。React允许将一个函数传递给setState方法,该方法接收之前的状态和属性数据并返回一个需要修改的状态对象,就像我们上面所做的那样。不仅没有问题,如果当前状态是根据之前的状态(state)和属性修改的,建议使用这种写法。ReactsetState调用后会发生什么?它是同步的还是异步的?(1)React中setState之后会发生什么在代码中调用setState函数后,React会将传入的参数对象与组件当前状态合并,然后触发调和过程(Reconciliation)。在协调过程之后,React将以一种相对高效的方式根据新的状态构建React元素树,并开始重新渲染整个UI界面。React拿到元素树后,React会自动计算新旧树的节点差异,然后根据差异最小化界面的重新渲染。在差异计算算法中,React可以比较准确地知道哪些位置发生了变化,应该如何变化,这保证了按需更新而不是完全重新渲染。如果短时间内频繁设置setState。React会将状态变化推送到栈上,并在合适的时间批量更新状态和视图,以提高性能。(2)setState是同步的还是异步的?如果所有的setStates都是同步的,那么意味着每次执行setState(可能在一个同步代码中,多个setStates),vnodediff+dom修改都会重新修改,这对性能很重要。非常糟糕。如果是异步的,可以将同步代码中的多个setState组合成一个组件更新。所以默认是异步的,但在某些情况下是同步的。setState不是纯同步/异步的,其性能会根据调用场景的不同而不同。源码中使用isBatchingUpdates判断setState是先存入状态队列还是直接更新。如果值为true,则执行异步操作,如果为false,则直接更新。异步:在React可以控制的地方确实如此。例如,在React生命周期事件和合成事件中,会遵循合并操作和延迟更新的策略。同步:在React无法控制的地方,比如原生事件,具体在addEventListener、setTimeout、setInterval等事件中,只能同步更新。一般认为,异步设计的目的是优化性能,减少渲染次数:setState设计成异步的,可以显着提升性能。如果每次调用setState都进行update,意味着会频繁调用render函数,界面会重新渲染,效率很低;最好的方式应该是获取多个更新,然后进行批量更新;如果synchronousstate更新了,但是render函数还没有执行,所以state和props不能保持同步。state和props不能保持一致性,会导致开发中出现很多问题;使用state要注意什么?注意以下几点。不要直接更新状态。状态更新可能是异步的。应该合并状态更新。数据从上到下流动的理解React-Intl,它是如何工作的?React-intl是Yahoo的语言国际化开源项目FormatJS的一部分,通过它提供可以绑定到ReactJS的组件和API。React-intl提供了两种使用方式,一种是引用React组件,另一种是直接调用API。官方推荐在React项目中使用前者。只有在不能使用React组件的地方,框架才应该提供API。它提供了一系列React组件,包括数字格式化、字符串格式化、日期格式化等。在React-intl中,可以配置不同的语言包,其工作原理是根据需要在语言包之间切换。如何比较diff算法?仅用于同级比较,跨级dom不会被复用。不同类型的节点生成的dom树是不一样的。此时会直接销毁旧节点和后代节点,新创建的节点可以使用key对元素进行diff的过程提供线索以供重用。Single-nodediff单点diff有以下几种情况:相同的key和type表示如果key不同则节点可以复用,直接标记为删除节点,然后新建的节点有相同的key和不同的类型,节点和兄弟节点被标记为删除,然后新创建的节点在Redux中使用Action需要注意哪些问题呢?在Redux中使用Action时,Action文件中尽量保持Action文件的纯净,传入什么数据就返回什么。请求的数据最好和Action方法分开,以保持Action的纯净。React中的Portal是什么?门户提供了一种很好的方式来将子节点呈现给DOM节点而不是父组件。第一个参数(child)是任何可渲染的React子元素,例如元素、字符串或片段。第二个参数(容器)是一个DOM元素。ReactDOM.createPortal(child,container)React中refs的作用是什么?有哪些应用场景?Refs提供了一种访问在render方法中创建的React元素或DOM节点的方法。应谨慎使用Refs。Refs更适合以下场景:处理焦点、文本选择或媒体控制以触发必要的动画。集成第三方DOM库Refs是使用React.createRef()方法创建的,它通过ref属性附加到React元素上。要在整个组件中使用Refs,您需要在构造函数中将ref分配给它的实例属性:{return}}constructor答案是:在构造函数中,当你需要使用props的值时,需要调用super(props)类语法糖会帮你定义默认一个构造函数,所以当你不需要使用构造函数时,你不需要自己定义它。自己定义构造函数的时候,一定要写super(),否则拿不到this。当你想在构造函数中使用props的值时,需要将props参数传入super并调用super(props),否则只需要写super()