什么起因会促使你脱离 create-react-app 的依赖
当你想去配置 webpack 或 babel presets。
React 16中新生命周期有哪些
对于 React16 开始利用的新生命周期: 能够看出,React16 自上而下地对生命周期做了另一种维度的解读:
- Render 阶段:用于计算一些必要的状态信息。这个阶段可能会被 React 暂停,这一点和 React16 引入的 Fiber 架构(咱们前面会重点解说)是无关的;
- Pre-commit阶段:所谓“commit”,这里指的是“更新真正的 DOM 节点”这个动作。所谓 Pre-commit,就是说我在这个阶段其实还并没有去更新实在的 DOM,不过 DOM 信息曾经是能够读取的了;
- Commit 阶段:在这一步,React 会实现实在 DOM 的更新工作。Commit 阶段,咱们能够拿到实在 DOM(包含 refs)。
与此同时,新的生命周期在流程方面,依然遵循“挂载”、“更新”、“卸载”这三个狭义的划分形式。它们别离对应到:
挂载过程:
- constructor
- getDerivedStateFromProps
- render
- componentDidMount
更新过程:
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
卸载过程:
- componentWillUnmount
React.forwardRef是什么?它有什么作用?
React.forwardRef 会创立一个React组件,这个组件可能将其承受的 ref 属性转发到其组件树下的另一个组件中。这种技术并不常见,但在以下两种场景中特地有用:
- 转发 refs 到 DOM 组件
- 在高阶组件中转发 refs
为什么虚构 dom 会进步性能
虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要 的 dom 操作,从而进步性能
具体实现步骤如下:
- 用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树, 插到文档当中;
- 当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记 录两棵树差别;
- 把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
vue 或者react 优化整体优化
- 虚构dom
为什么虚构 dom 会进步性能?(必考)
虚构 dom 相当于在 js 和实在 dom 两头加了一个缓存,利用 dom diff 算法防止了没有必要的 dom 操作,从而进步性能。
用 JavaScript 对象构造示意 DOM 树的构造;而后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,从新结构一棵新的对象树。而后用新的树和旧的树进行比拟,记录两棵树差别把 2 所记录的差别利用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
对componentWillReceiveProps 的了解
该办法当props
发生变化时执行,初始化render
时不执行,在这个回调函数外面,你能够依据属性的变动,通过调用this.setState()
来更新你的组件状态,旧的属性还是能够通过this.props
来获取,这里调用更新状态是平安的,并不会触发额定的render
调用。
应用益处: 在这个生命周期中,能够在子组件的render函数执行前获取新的props,从而更新子组件本人的state。 能够将数据申请放在这里进行执行,须要传的参数则从componentWillReceiveProps(nextProps)中获取。而不用将所有的申请都放在父组件中。于是该申请只会在该组件渲染时才会收回,从而加重申请累赘。
componentWillReceiveProps在初始化render的时候不会执行,它会在Component承受到新的状态(Props)时被触发,个别用于父组件状态更新时子组件的从新渲染。
参考 前端进阶面试题具体解答
hooks父子传值
父传子在父组件中用useState申明数据 const [ data, setData ] = useState(false)把数据传递给子组件<Child data={data} />子组件接管export default function (props) { const { data } = props console.log(data)}子传父子传父能够通过事件办法传值,和父传子有点相似。在父组件中用useState申明数据 const [ data, setData ] = useState(false)把更新数据的函数传递给子组件<Child setData={setData} />子组件中触发函数更新数据,就会间接传递给父组件export default function (props) { const { setData } = props setData(true)}如果存在多个层级的数据传递,也可按照此办法顺次传递// 多层级用useContextconst User = () => { // 间接获取,不必回调 const { user, setUser } = useContext(UserContext); return <Avatar user={user} setUser={setUser} />;};
React 组件中怎么做事件代理?它的原理是什么?
React基于Virtual DOM实现了一个SyntheticEvent层(合成事件层),定义的事件处理器会接管到一个合成事件对象的实例,它合乎W3C规范,且与原生的浏览器事件领有同样的接口,反对冒泡机制,所有的事件都主动绑定在最外层上。
在React底层,次要对合成事件做了两件事:
- 事件委派: React会把所有的事件绑定到构造的最外层,应用对立的事件监听器,这个事件监听器上维持了一个映射来保留所有组件外部事件监听和处理函数。
- 主动绑定: React组件中,每个办法的上下文都会指向该组件的实例,即主动绑定this为以后组件。
react性能优化是哪个周期函数
shouldComponentUpdate
这个办法用来判断是否须要调用render办法从新描述dom。因为dom的描述十分耗费性能,如果咱们能在shouldComponentUpdate方
法中可能写出更优化的dom diff
算法,能够极大的进步性能
如何通知 React 它应该编译生产环境版
通常状况下咱们会应用Webpack
的DefinePlugin
办法来将NODE_ENV
变量值设置为production
。编译版本中React
会疏忽propType
验证以及其余的告警信息,同时还会升高代码库的大小,React
应用了Uglify
插件来移除生产环境下不必要的正文等信息
何为 redux
Redux 的根本思维是整个利用的 state 放弃在一个繁多的 store 中。store 就是一个简略的 javascript 对象,而扭转利用 state 的惟一形式是在利用中触发 actions,而后为这些 actions 编写 reducers 来批改 state。整个 state 转化是在 reducers 中实现,并且不应该有任何副作用。
这段代码有什么问题?
class App extends Component { constructor(props) { super(props); this.state = { username: "有课前端网", msg: " ", }; } render() { return <div> {this.state.msg}</div>; } componentDidMount() { this.setState((oldState, props) => { return { msg: oldState.username + " - " + props.intro, }; }); }}
render ( < App intro=" 前端技术业余学习平台"></App>,ickt )
在页面中失常输入“有课前端网-前端技术业余学习平台”。然而这种写法很少应用,并不是罕用的写法。React容许对 setState办法传递一个函数,它接管到先前的状态和属性数据并返回一个须要批改的状态对象,正如咱们在下面所做的那样。它岂但没有问题,而且如果依据以前的状态( state)以及属性来批改以后状态,举荐应用这种写法。
React setState 调用之后产生了什么?是同步还是异步?
(1)React中setState后产生了什么
在代码中调用setState函数之后,React 会将传入的参数对象与组件以后的状态合并,而后触发和谐过程(Reconciliation)。通过和谐过程,React 会以绝对高效的形式依据新的状态构建 React 元素树并且着手从新渲染整个UI界面。
在 React 失去元素树之后,React 会主动计算出新的树与老树的节点差别,而后依据差别对界面进行最小化重渲染。在差别计算算法中,React 可能绝对准确地晓得哪些地位产生了扭转以及应该如何扭转,这就保障了按需更新,而不是全副从新渲染。
如果在短时间内频繁setState。React会将state的扭转压入栈中,在适合的机会,批量更新state和视图,达到进步性能的成果。
(2)setState 是同步还是异步的
如果所有setState是同步的,意味着每执行一次setState时(有可能一个同步代码中,屡次setState),都从新vnode diff + dom批改,这对性能来说是极为不好的。如果是异步,则能够把一个同步代码中的多个setState合并成一次组件更新。所以默认是异步的,然而在一些状况下是同步的。
setState 并不是单纯同步/异步的,它的体现会因调用场景的不同而不同。在源码中,通过 isBatchingUpdates 来判断setState 是先存进 state 队列还是间接更新,如果值为 true 则执行异步操作,为 false 则间接更新。
- 异步: 在 React 能够管制的中央,就为 true,比方在 React 生命周期事件和合成事件中,都会走合并操作,提早更新的策略。
- 同步: 在 React 无法控制的中央,比方原生事件,具体就是在 addEventListener 、setTimeout、setInterval 等事件中,就只能同步更新。
个别认为,做异步设计是为了性能优化、缩小渲染次数:
setState
设计为异步,能够显著的晋升性能。如果每次调用setState
都进行一次更新,那么意味着render
函数会被频繁调用,界面从新渲染,这样效率是很低的;最好的方法应该是获取到多个更新,之后进行批量更新;- 如果同步更新了
state
,然而还没有执行render
函数,那么state
和props
不能放弃同步。state
和props
不能放弃一致性,会在开发中产生很多的问题;
应用状态要留神哪些事件?
要留神以下几点。
- 不要间接更新状态
- 状态更新可能是异步的
- 状态更新要合并。
- 数据从上向下流动
对 React-Intl 的了解,它的工作原理?
React-intl是雅虎的语言国际化开源我的项目FormatJS的一部分,通过其提供的组件和API能够与ReactJS绑定。
React-intl提供了两种应用办法,一种是援用React组件,另一种是间接调取API,官网更加举荐在React我的项目中应用前者,只有在无奈应用React组件的中央,才应该调用框架提供的API。它提供了一系列的React组件,包含数字格式化、字符串格式化、日期格式化等。
在React-intl中,能够配置不同的语言包,他的工作原理就是依据须要,在语言包之间进行切换。
diff算法如何比拟?
- 只对同级比拟,跨层级的dom不会进行复用
- 不同类型节点生成的dom树不同,此时会间接销毁老节点及子孙节点,并新建节点
- 能够通过key来对元素diff的过程提供复用的线索
- 单节点diff
- 单点diff有如下几种状况:
- key和type雷同示意能够复用节点
- key不同间接标记删除节点,而后新建节点
- key雷同type不同,标记删除该节点和兄弟节点,而后新创建节点
在 Redux中应用 Action要留神哪些问题?
在Redux中应用 Action的时候, Action文件里尽量放弃 Action文件的污浊,传入什么数据就返回什么数据,最妤把申请的数据和 Action办法分来到,以放弃 Action的污浊。
react中的Portal是什么?
Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的形式。
第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或碎片。
第二个参数(container)则是一个 DOM 元素。
ReactDOM.createPortal(child, container)
React中refs的作用是什么?有哪些利用场景?
Refs 提供了一种形式,用于拜访在 render 办法中创立的 React 元素或 DOM 节点。Refs 应该审慎应用,如下场景应用 Refs 比拟适宜:
- 解决焦点、文本抉择或者媒体的管制
- 触发必要的动画
- 集成第三方 DOM 库
Refs 是应用 React.createRef() 办法创立的,他通过 ref 属性附加到 React 元素上。
要在整个组件中应用 Refs,须要将 ref 在构造函数中调配给其实例属性:
class MyComponent extends React.Component { constructor(props) { super(props) this.myRef = React.createRef() } render() { return <div ref={this.myRef} /> }}
constructor
答案是:在 constructor 函数外面,须要用到props的值的时候,就须要调用 super(props)
- class语法糖默认会帮你定义一个constructor,所以当你不须要应用constructor的时候,是能够不必本人定义的
- 当你本人定义一个constructor的时候,就肯定要写super(),否则拿不到this
- 当你在constructor外面想要应用props的值,就须要传入props这个参数给super,调用super(props),否则只须要写super()