哈尔滨自助模板建站,重庆开发app的公司,云南建筑工程网,深圳招聘网站哪个好面试题 65. 在使用 React Router时#xff0c;如何获取当前页面的路由或浏览器中地址栏中的地址#xff1f;
参考回答#xff1a;
在当前组件的 props中#xff0c;包含 location属性对象#xff0c;包含当前页面路由地址信息#xff0c;在 match中存储当前路由的参数等…面试题 65. 在使用 React Router时如何获取当前页面的路由或浏览器中地址栏中的地址
参考回答
在当前组件的 props中包含 location属性对象包含当前页面路由地址信息在 match中存储当前路由的参数等数据信息。可以直接通过 this .props使用它们面试题 66. 简述React中什么是纯组件
参考回答
纯组件是可以编写的最简单和最快的组件。它们可以替换任何只有 render() 的组件。这些组件增强了代码的简单性和应用程序的性能。面试题 67. 解释React Reducer的作用
参考回答
Reducers 是纯函数它指定应用程序的状态如何响应 ACTION 变化。Reducers 通过接收之前的状态和动作来工作然后它返回一个新状态。它根据操作的类型确定需要进行何种类型的更新然后返回新值。 如果不需要做任何工作它会按原样返回先前的状态面试题 68. 请简述Redux 与 Flux 有何不同
参考回答
1.Redux中只有一个store而Flux中有多个store来存储应用数据并在store里面执行更新逻辑当store变化的时候再通知controller-view更新自己的数据Redux是将各个store整合成一个完整的store,并且可以根据这个store来得到完整的state而且更新的逻辑也不再store中而是在reducer采用纯函数中。2.Redux没有Dispatcher这个概念。它使用的是reducer来进行事件的处理reducer是一个纯函数(preState, action) newState,在Redux应用中可能有多个reducer每一reducer来负责维护应用整体state树中某一部分多个reducer通过combineReducers方法合成一个根reducer,来维护整个state面试题 69. React 如何更新组件状态
参考回答
可以使用 this.setState() 更新组件的状态
class MyComponent extends React.Component {
constructor() {
super();
this.state {
name: Maxx,
id: 101
}
}
render()
{
setTimeout((){this.setState({name:Jaeha, id:222})},2000)
return (
Hello {this.state.name}
Your Id is {this.state.id}
);
}
}
ReactDOM.render(
, document.getElementById(content)
);
面试题 70. React 中的箭头函数是什么它是如何使用的
参考回答
箭头函数更多是用于编写函数表达式的简短语法。它们也被称为“胖箭头”函数。这些函数允许正确绑定组件的上下文因为在 ES6 中自动绑定默认不可用。箭头函数在处理高阶函数时最有用。登录后复制
//General way
render() {
return();
}
//With Arrow Function
render() {
return(
this.handleOnChange(e) } /
);
}面试题 71. 详细阐述Redux有什么优势
参考回答
结果的可预测性—— 因为总是有一个真实的来源即商店关于如何将当前状态与应用程序的动作和其他部分同步没有任何混淆。
可维护性——代码变得更容易维护具有可预测的结果和严格的结构。
服务器端渲染—— 您只需要将在服务器上创建的商店传递到客户端。这对于初始渲染非常有用并提供更好的用户体验因为它优化了应用程序性能。
开发人员工具——从操作到状态更改开发人员可以实时跟踪应用程序中发生的一切。
社区和生态系统 ——Redux 背后有一个庞大的社区这使得它使用起来更加迷人。一个庞大的人才社区为图书馆的改进做出了贡献并用它开发了各种应用程序。
易于测试 ——Redux 的代码主要是小、纯和隔离的函数。这使得代码可测试且独立。
组织——Redux 对代码的组织方式 非常精确这使得当团队使用代码时代码更加一致和容易。面试题 72. 解释为什么在React Router v4 中使用switch 关键字
参考回答
switch 是用来封装Router内部的多条路由的。当您只想显示要在多个定义的路由中呈现的单个路由时使用 “switch”关键字 。 使用中的 标记将键入的 URL 与已定义的路由按顺序匹配。 当找到第一个匹配项时它会呈现指定的路由。从而绕过其余 路线。面试题 73. 编写代码实现如何 React.createElement
参考回答
const element (Hello, world!)
const element React.createElement(
h1, {
className: greeting
}
,
Hello, world!面试题 74. 请用源码解释React setState 调用的原理
参考回答
具体的执行过程如下源码级解析首先调用了setState 入口函数入口函数在这里就是充当一个分发器的角色根据入参的不同将其分发到不同的功能函数中去
ReactComponent.prototype.setState function (partialState, callback) {
this.updater.enqueueSetState(this, partialState);
if (callback) {
this.updater.enqueueCallback(this, callback, setState);
}
};
在 enqueueUpdate 方法中引出了一个关键的对象——batchingStrategy该对象所具备的isBatchingUpdates 属性直接决定了当下是要走更新流程还是应该排队等待如果轮到执行就调用 batchedUpdates 方法来直接发起更新流程。由此可以推测batchingStrategy 或许正是 React 内部专门用于管控批量更新的对象。
function enqueueUpdate(component) {
ensureInjected();
// 注意这一句是问题的关键isBatchingUpdates标识着当前是否处于批量创建/更新组件的阶段
if (!batchingStrategy.isBatchingUpdates) {
// 若当前没有处于批量创建/更新组件的阶段则立即更新组件
batchingStrategy.batchedUpdates(enqueueUpdate, component);
return;
}
// 否则先把组件塞入 dirtyComponents 队列里让它“再等等”
dirtyComponents.push(component);
if (component._updateBatchNumber null) {
component._updateBatchNumber updateBatchNumber 1;
}
}
注意batchingStrategy 对象可以理解为“锁管理器”。这里的“锁”是指 React 全局唯一的 isBatchingUpdates 变量isBatchingUpdates 的初始值是 false意味着“当前并未进行任何批量更新操作”。每当 React 调用 batchedUpdate 去执行更新动作时会先把这个锁给“锁上”置为 true表明“现在正处于批量更新过程中”。当锁被“锁上”的时候任何需要更新的组件都只能暂时进入 dirtyComponents 里排队等候下一次的批量更新而不能随意“插队”。此处体现的“任务锁”的思想是 React 面对大量状态仍然能够实现有序分批处理的基石面试题 75. 简述shouldComponentUpdate 作用为什么它很重要
参考回答
组件状态数据或者属性数据发生更新的时候组件会进入存在期视图会渲染更新。在生命周期方法 should ComponentUpdate中允许选择退出某些组件和它们的子组件的和解过程。
和解的最终目标是根据新的状态以最有效的方式更新用户界面。如果我们知道用户界面的某一部分不会改变那么没有理由让 React弄清楚它是否应该更新渲染。通过在 shouldComponentUpdate方法中返回 false, React将让当前组件及其所有子组件保持与当前组件状态相同面试题 76. 简述什么是 React Context?
参考回答
Context 通过组件树提供了一个传递数据的方法从而避免了在每一个层级手动的传递 props 属性面试题 77. React中如何避免不必要的render
参考回答
React 基于虚拟 DOM 和高效 Diff 算法的完美配合实现了对 DOM 最小粒度的更新。大多数情况下React 对 DOM 的渲染效率足以业务日常。但在个别复杂业务场景下性能问题依然会困扰我们。此时需要采取一些措施来提升运行性能其很重要的一个方向就是避免不必要的渲染Render。这里提下优化的点shouldComponentUpdate 和 PureComponent
在 React 类组件中可以利用 shouldComponentUpdate或者 PureComponent 来减少因父组件更新而触发子组件的 render从而达到目的。shouldComponentUpdate 来决定是否组件是否重新渲染如果不希望组件重新渲染返回 false 即可。利用高阶组件
在函数组件中并没有 shouldComponentUpdate 这个生命周期可以利用高阶组件封装一个类似 PureComponet 的功能使用 React.memo
React.memo 是 React 16.6 新的一个 API用来缓存组件的渲染避免不必要的更新其实也是一个高阶组件与 PureComponent 十分类似但不同的是 React.memo只能用于函数组件面试题 78. 简述React- Router有几种形式
参考回答
有以下几种形式。
HashRouter通过散列实现路由要带#。
BrowerRouter利用HTML5中 history API实现需要服务器端支持兼容性不是很好面试题 79. 简述什么是 Children 属性
参考回答
在JSX表达式中一个开始标签(比如)和一个关闭标签(比如)之间的内容会作为一个特殊的属性props.children被自动传递给包含着它的组件。这个属性有许多可用的方法包括 React.Children.mapReact.Children.forEach React.Children.count React.Children.onlyReact.Children.toArray面试题 80. 解释为什么调用 setState 而不是直接改变 state
参考回答
如果您尝试直接改变组件的状态React 将无法得知它需要重新渲染组件。通过使用setState()方法React 可以更新组件的UI。另外您还可以谈谈如何不保证状态更新是同步的。如果需要基于另一个状态或属性更新组件的状态请向setState()传递一个函数该函数将 state 和 props 作为其两个参数this.setState((state, props) ({
counter: state.counter props.increment
}));面试题 81. 请简述React父子组件的通信方式
参考回答
父组件向子组件通信父组件通过 props 向子组件传递需要的信息。// 子组件: Child
const Child props {
return{props.name}}
// 父组件 Parent
const Parent (){
return
}
子组件向父组件通信: props回调的方式。// 子组件: Child
const Child props {
const cb msg {
return (){
props.callback(msg)
}
}
return (button onClick{cb(你好!)}你好/button)
}
// 父组件 Parent
class Parent extends Component {
callback(msg){
console.log(msg)
}
render(){
return
}
}面试题 82. 简述 state 更新流程
参考回答
shouldComponentUpdate: 当组件的 state 或 props 发生改变时都会首先触发这个生命周期函数。它会接收两个参数nextProps, nextState——它们分别代表传入的新 props 和新的 state 值。拿到这两个值之后我们就可以通过一些对比逻辑来决定是否有 re-render重渲染的必要了。如果该函数的返回值为 false则生命周期终止反之继续
注意此方法仅作为性能优化的方式而存在。不要企图依靠此方法来“阻止”渲染因为这可能会产生 bug。应该考虑使用内置的 PureComponent 组件而不是手动编写 shouldComponentUpdate()componentWillUpdate当组件的 state 或 props 发生改变时会在渲染之前调用 componentWillUpdate。componentWillUpdate 是 React16 废弃的三个生命周期之一。过去我们可能希望能在这个阶段去收集一些必要的信息比如更新前的 DOM 信息等等现在我们完全可以在 React16 的 getSnapshotBeforeUpdate 中去做这些事componentDidUpdatecomponentDidUpdate() 会在UI更新后会被立即调用。它接收 prevProps上一次的 props 值作为入参也就是说在此处我们仍然可以进行 props 值对比面试题 83. 简述React中的Portal是什么
参考回答
Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。
第一个参数child是任何可渲染的 React 子元素例如一个元素字符串或碎片。
第二个参数container则是一个 DOM 元素。
ReactDOM.createPortal(child, container)面试题 84. 解释 React 中 render() 的目的和作用
参考回答
每个React组件强制要求必须有一个 render()。它返回一个 React 元素是原生 DOM 组件的表示。如果需要渲染多个 HTML 元素则必须将它们组合在一个封闭标记内例如form、group、div
等。此函数必须保持纯净即必须每次调用时都返回相同的结果面试题 85. React如何获取组件对应的DOM元素
参考回答
可以用ref来获取某个子节点的实例然后通过当前class组件实例的一些特定属性来直接获取子节点实例。
ref有三种实现方法:
字符串格式字符串格式这是React16版本之前用得最多的例如span函数格式ref对应一个方法该方法有一个参数也就是对应的节点实例例如
this.info ele}createRef方法React 16提供的一个API使用React.createRef()来实现面试题 86. 说明React16版本的reconciliation阶段和commit阶段是什么
参考回答
reconciliation阶段包含的主要工作是对current tree 和 new tree 做diff计算找出变化部分。进行遍历、对比等是可以中断歇一会儿接着再来。
commit阶段是对上一阶段获取到的变化部分应用到真实的DOM树中是一系列的DOM操作。不仅要维护更复杂的DOM状态而且中断后再继续会对用户体验造成影响。在普遍的应用场景下此阶段的耗时比diff计算等耗时相对短面试题 87. 请说明React中getDefaultProps 的作用
参考回答
通过实现组件的getDefaultProps对属性设置默认值ES5的写法var ShowTitle React.createClass({
getDefaultProps:function(){
return{
title : React
}
},
render : function(){
returnh1{this.props.title}/h1}
});面试题 88. 简述React 组件中怎么做事件代理它的原理是什么
参考回答
React基于Virtual DOM实现了一个SyntheticEvent层合成事件层定义的事件处理器会接收到一个合成事件对象的实例它符合W3C标准且与原生的浏览器事件拥有同样的接口支持冒泡机制所有的事件都自动绑定在最外层上。在React底层主要对合成事件做了两件事1 事件委派 React会把所有的事件绑定到结构的最外层使用统一的事件监听器这个事件监听器上维持了一个映射来保存所有组件内部事件监听和处理函数。2 自动绑定 React组件中每个方法的上下文都会指向该组件的实例即自动绑定this为当前组件面试题 89. 请简述React组件的构造函数的作用
参考回答
构造函数主要用于两个目的通过将对象分配给this.state来初始化本地状态
将事件处理程序方法绑定到实例上
所以当在React class中需要设置state的初始值或者绑定事件时需要加上构造函数官方Democlass LikeButton extends React.Component {
constructor() {
super();
this.state {
liked: false
};
this.handleClick this.handleClick.bind(this);
}
handleClick() {
this.setState({liked: !this.state.liked});
}
render() {
const text this.state.liked ? liked : haven\t liked;
return (You {text} this. Click to toggle.);
}
}
ReactDOM.render(
,
document.getElementById(example)
);构造函数用来新建父类的this对象子类必须在constructor方法中调用super方法否则新建实例时会报错因为子类没有自己的this对象而是继承父类的this对象然后对其进行加工。如果不调用super方法子类就得不到this对象。注意constructor () 必须配上 super(), 如果要在constructor 内部使用 this.props 就要 传入props , 否则不用
JavaScript中的 bind 每次都会返回一个新的函数, 为了性能等考虑, 尽量在constructor中绑定事件面试题 90. 简述React Hooks在平时开发中需要注意的问题和原因
参考回答
1不要在循环条件或嵌套函数中调用Hook必须始终在 React函数的顶层使用Hook
这是因为React需要利用调用顺序来正确更新相应的状态以及调用相应的钩子函数。一旦在循环或条件分支语句中调用Hook就容易导致调用顺序的不一致性从而产生难以预料到的后果。2使用useState时候使用pushpopsplice等直接更改数组对象的坑
使用push直接更改数组无法获取到新值应该采用析构方式但是在class里面不会有这个问题。代码示例function Indicatorfilter() {
let [num,setNums] useState([0,1,2,3])
const test () {
// 这里坑是直接采用push去更新num
// setNums(num)是无法更新num的
// 必须使用num [...num ,1]
num.push(1)
// num [...num ,1]
setNums(num)
}
return (测试{num.map((item,index) (
{item}))})
}class Indicatorfilter extends React.Component{
constructor(props:any){
super(props)
this.state {
nums:[1,2,3]
}
this.test this.test.bind(this)
}test(){
// class采用同样的方式是没有问题的
this.state.nums.push(1)
this.setState({
nums: this.state.nums
})
}render(){
let {nums} this.state
return(测试{nums.map((item:any,index:number) (
{item}))})
}
}3useState设置状态的时候只有第一次生效后期需要更新状态必须通过useEffectTableDeail是一个公共组件在调用它的父组件里面我们通过set改变columns的值以为传递给TableDeail 的 columns是最新的值所以tabColumn每次也是最新的值但是实际tabColumn是最开始的值不会随着columns的更新而更新const TableDeail ({ columns,}:TableData) {
const [tabColumn, setTabColumn] useState(columns)
}// 正确的做法是通过useEffect改变这个值
const TableDeail ({ columns,}:TableData) {
const [tabColumn, setTabColumn] useState(columns)
useEffect(() {setTabColumn(columns)},[columns])
}
4善用useCallback
父组件传递给子组件事件句柄时如果我们没有任何参数变动可能会选用useMemo。但是每一次父组件渲染子组件即使没变化也会跟着渲染一次。5不要滥用useContext
可以使用基于 useContext 封装的状态管理工具。面试题 91. 在React中组件的this.state和setState有什么区别
参考回答
this.state通常是用来初始化state的this.setState是用来修改state值的。如果初始化了state之后再使用this.state之前的state会被覆盖掉如果使用this.setState只会替换掉相应的state值。所以如果想要修改state的值就需要使用setState而不能直接修改state直接修改state之后页面是不会更新的。面试题 92. 如何配置 React-Router 实现路由切换
参考回答
1使用 组件
路由匹配是通过比较 的 path 属性和当前地址的 pathname 来实现的。当一个 匹配成功时它将渲染其内容当它不匹配时就会渲染 null。没有路径的 将始终被匹配。
// when location { pathname: /about }
About
}
/ // renders
Contact
}
/ // renders null
Always
}
/ // renders
2结合使用 组件和 组件
用于将 分组。Home
}
/
About
}
/
Contact
}
/不是分组 所必须的但他通常很有用。 一个 会遍历其所有的子 元素并仅渲染与当前地址匹配的第一个元素。
3使用 、 、 组件
组件来在你的应用程序中创建链接。无论你在何处渲染一个 都会在应用程序的 HTML 中渲染锚。
Home
// Home
是一种特殊类型的 当它的 to属性与当前地址匹配时可以将其定义为活跃的。
// location { pathname: /react }React// React
当我们想强制导航时可以渲染一个当一个渲染时它将使用它的to属性进行定向面试题 93. 简述React中class定义的组件和function定义的组件的区别
参考回答
function定义的组件没有this指向的问题
class定义的组件有自己的局部状态this.state和自己的生命周期函数function定义的组件是无状态组件但是在16.8之后可以用hooksuseEffect来模拟组件的局部状态和生命周期。
官方建议使用function来定义组件写法简单并且便于理解。面试题 94. 简述React中hooks是如何模拟组件的生命周期的
参考回答
componentDidMount
function Example() {
useEffect(() console.log(mounted), []);
return null;
}
复制代码
useEffect 拥有两个参数第一个参数作为回调函数会在浏览器布局和绘制完成后调用因此它不会阻碍浏览器的渲染进程。 第二个参数是一个数组
当数组存在并有值时如果数组中的任何值发生更改则每次渲染后都会触发回调。
当它不存在时每次渲染后都会触发回调。
当它是一个空列表时回调只会被触发一次类似于 componentDidMount。
componentDidUpdate
useEffect(() console.log(count updated),[count]);
复制代码
componentWillUnmount
useEffect(() {
return () {
console.log(will unmount);
}
}
, []);
当在 useEffect 的回调函数中返回一个函数时这个函数会在组件卸载前被调用。我们可以在这里面清除定时器或事件监听器。面试题 95. 简述什么是React中的错误边界
参考回答
React16.X中引入了错误边界Error Boundaries概念。
它可以捕获它的子组件中产生的错误类似于try-catch只不过是以react组件的形式来实现的。
有了错误边界即使某个组件的结果有错误整个React程序挂载也不会被挂掉。只有出错的那个组件会显示一个后备界面而整个程序仍然完全正常运行。
这里的componentDidCatch()函数使用方法和JavaScript中的catch {}代码块差不多但只能用于组件。只有类组件才可以成为错误边界。
在componentDidCatch()函数内部我们把hasError状态设置为true。然后在渲染方法中检查那个状态。如果出错状态是真就渲染后备界面如果是false就把想渲染的React组件界面当作子组件界面渲染出来。
尽管如此以下错误Error Boundaries依旧无法捕获1 事件错误
2 Error Boundaries本身的错误
3 异步代码面试题 96. 叙述React如何使用Redux使用流程 ?
参考回答
1 在脚手架中安装react-redux
2 使用createStore去创建一个全局的store用来保存所有的statecreateStore接收一个reducer作为参数你可以使用combineReducers传入多个reducer。
3 在reducer中接收两个参数第一个参数表示数据的初始状态第二个参数表示action并且reducer会返回一个新的对象作为数据这样的话可以不进行原始对象的比较性能会提高。
4 想要改变数据的话就是view通过dispatch去派发一个action去执行相应的reducer并且在store中进行更新store改变的话view就会重新渲染。
5 我们可能要使用react-redux中的connect和Provider方法 去关联我们的数据。Provider通过context上下文向子组件提供store,connect把redux中的数据和组件中的props做关联这里用到的方法是mapStateToProps把store中的数据去映射到组件的props中这样在组件中就可以通过props去访问到redux中的数据。
6 如果需要发送异步请求的话还需要react-thunk插件需要在creaceStore中做一个配置。