2022前端社招React面试题 附答案
React视频解说 点击学习
全副视频:点击学习
1. React-Router的实现原理是什么?
客户端路由实现的思维:
基于 hash 的路由:通过监听
hashchange
事件,感知 hash 的变动
- 扭转 hash 能够间接通过 location.hash=xxx
基于 H5 history 路由:
- 扭转 url 能够通过 history.pushState 和 resplaceState 等,会将URL压入堆栈,同时可能利用
history.go()
等 API - 监听 url 的变动能够通过自定义事件触发实现
- 扭转 url 能够通过 history.pushState 和 resplaceState 等,会将URL压入堆栈,同时可能利用
react-router 实现的思维:
- 基于
history
库来实现上述不同的客户端路由实现思维,并且可能保留历史记录等,磨平浏览器差别,下层无感知 - 通过保护的列表,在每次 URL 发生变化的回收,通过配置的 路由门路,匹配到对应的 Component,并且 render
2. 如何配置 React-Router 实现路由切换
(1)应用<Route>
组件
路由匹配是通过比拟 <Route>
的 path 属性和以后地址的 pathname 来实现的。当一个 <Route>
匹配胜利时,它将渲染其内容,当它不匹配时就会渲染 null。没有门路的 <Route>
将始终被匹配。
// when location = { pathname: '/about' }<Route path='/about' component={About}/> // renders <About/><Route path='/contact' component={Contact}/> // renders null<Route component={Always}/> // renders <Always/>复制代码
(2)联合应用 <Switch>
组件和 <Route>
组件
<Switch>
用于将 <Route>
分组。
<Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> <Route path="/contact" component={Contact} /></Switch>复制代码
<Switch>
不是分组 <Route>
所必须的,但他通常很有用。 一个 <Switch>
会遍历其所有的子 <Route>
元素,并仅渲染与以后地址匹配的第一个元素。
(3)应用 <Link>、 <NavLink>、<Redirect>
组件
<Link>
组件来在你的应用程序中创立链接。无论你在何处渲染一个<Link>
,都会在应用程序的 HTML 中渲染锚(<a>
)。
<Link to="/">Home</Link> // <a href='/'>Home</a>复制代码
是一种非凡类型的 当它的 to属性与以后地址匹配时,能够将其定义为"沉闷的"。
// location = { pathname: '/react' }<NavLink to="/react" activeClassName="hurray"> React</NavLink>// <a href='/react' className='hurray'>React</a>复制代码
当咱们想强制导航时,能够渲染一个<Redirect>
,当一个<Redirect>
渲染时,它将应用它的to属性进行定向。
3. React-Router怎么设置重定向?
应用<Redirect>
组件实现路由的重定向:
<Switch> <Redirect from='/users/:id' to='/users/profile/:id'/> <Route path='/users/profile/:id' component={Profile}/></Switch>复制代码
当申请 /users/:id
被重定向去 '/users/profile/:id'
:
- 属性
from: string
:须要匹配的将要被重定向门路。 - 属性
to: string
:重定向的 URL 字符串 - 属性
to: object
:重定向的 location 对象 - 属性
push: bool
:若为真,重定向操作将会把新地址退出到拜访历史记录外面,并且无奈回退到后面的页面。
4. react-router 里的 Link 标签和 a 标签的区别
从最终渲染的 DOM 来看,这两者都是链接,都是 标签,区别是∶ <Link>
是react-router 里实现路由跳转的链接,个别配合<Route>
应用,react-router接管了其默认的链接跳转行为,区别于传统的页面跳转,<Link>
的“跳转”行为只会触发相匹配的<Route>
对应的页面内容更新,而不会刷新整个页面。
<Link>
做了3件事件:
- 有onclick那就执行onclick
- click的时候阻止a标签默认事件
- 依据跳转href(即是to),用history (web前端路由两种形式之一,history & hash)跳转,此时只是链接变了,并没有刷新页面而
<a>
标签就是一般的超链接了,用于从以后页面跳转到href指向的另一 个页面(非锚点状况)。
a标签默认事件禁掉之后做了什么才实现了跳转?
let domArr = document.getElementsByTagName('a')[...domArr].forEach(item=>{ item.addEventListener('click',function () { location.href = this.href })})
5. React-Router如何获取URL的参数和历史对象?
(1)获取URL的参数
- get传值
路由配置还是一般的配置,如:'admin'
,传参形式如:'admin?id='1111''
。通过this.props.location.search
获取url获取到一个字符串'?id='1111'
能够用url,qs,querystring,浏览器提供的api URLSearchParams对象或者本人封装的办法去解析出id的值。
- 动静路由传值
路由须要配置成动静路由:如path='/admin/:id'
,传参形式,如'admin/111'
。通过this.props.match.params.id
获得url中的动静路由id局部的值,除此之外还能够通过useParams(Hooks)
来获取
- 通过query或state传值
传参形式如:在Link组件的to属性中能够传递对象{pathname:'/admin',query:'111',state:'111'};
。通过this.props.location.state
或this.props.location.query
来获取即可,传递的参数能够是对象、数组等,然而存在毛病就是只有刷新页面,参数就会失落。
(2)获取历史对象
- 如果React >= 16.8 时能够应用 React Router中提供的Hooks
import { useHistory } from "react-router-dom";let history = useHistory();复制代码
2.应用this.props.history获取历史对象
let history = this.props.history;
6:React 中 refs 干嘛用的?
主题: React
难度: ⭐⭐
Refs
提供了一种拜访在render
办法中创立的 DOM 节点或者 React 元素的办法。在典型的数据流中,props
是父子组件交互的惟一形式,想要批改子组件,须要应用新的pros
从新渲染它。凡事有例外,某些状况下咱们须要在典型数据流外,强制批改子代,这个时候能够应用 Refs
。
咱们能够在组件增加一个 ref
属性来应用,该属性的值是一个回调函数,接管作为其第一个参数的底层 DOM 元素或组件的挂载实例。
class UnControlledForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' ref={(input) => this.input = input} /> <button type='submit'>Submit</button> </form> ) }}复制代码
请留神,input
元素有一个ref
属性,它的值是一个函数。该函数接管输出的理论 DOM 元素,而后将其放在实例上,这样就能够在 handleSubmit
函数外部拜访它。
常常被误会的只有在类组件中能力应用 refs
,然而refs
也能够通过利用 JS 中的闭包与函数组件一起应用。
function CustomForm ({handleSubmit}) { let inputElement return ( <form onSubmit={() => handleSubmit(inputElement.value)}> <input type='text' ref={(input) => inputElement = input} /> <button type='submit'>Submit</button> </form> )}
7:在 React 中如何处理事件
主题: React
难度: ⭐⭐
为了解决跨浏览器的兼容性问题,SyntheticEvent
实例将被传递给你的事件处理函数,SyntheticEvent
是 React 跨浏览器的浏览器原生事件包装器,它还领有和浏览器原生事件雷同的接口,包含 stopPropagation()
和 preventDefault()
。
比拟乏味的是,React 实际上并不将事件附加到子节点自身。React 应用单个事件侦听器侦听顶层的所有事件。这对性能有益处,也意味着 React 在更新 DOM 时不须要跟踪事件监听器。
8:如何创立 refs
主题: React
难度: ⭐⭐
Refs 是应用 React.createRef()
创立的,并通过 ref
属性附加到 React 元素。在结构组件时,通常将 Refs
调配给实例属性,以便能够在整个组件中援用它们。
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; }}复制代码
或者这样用:
class UserForm extends Component { handleSubmit = () => { console.log("Input Value is: ", this.input.value) } render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' ref={(input) => this.input = input} /> // Access DOM input in handle submit <button type='submit'>Submit</button> </form> ) }}
9:在结构函数调用 super
并将 props
作为参数传入的作用是啥?
主题: React
难度: ⭐⭐
在调用 super()
办法之前,子类构造函数无奈应用this
援用,ES6 子类也是如此。将 props
参数传递给 super()
调用的次要起因是在子构造函数中可能通过this.props
来获取传入的 props
。
传递 props
class MyComponent extends React.Component { constructor(props) { super(props); console.log(this.props); // { name: 'sudheer',age: 30 } }}复制代码
没传递 props
class MyComponent extends React.Component { constructor(props) { super(); console.log(this.props); // undefined // 然而 Props 参数依然可用 console.log(props); // Prints { name: 'sudheer',age: 30 } } render() { // 构造函数内部不受影响 console.log(this.props) // { name: 'sudheer',age: 30 } }}复制代码
下面示例揭示了一点。props
的行为只有在构造函数中是不同的,在构造函数之外也是一样的。
10:如何 React.createElement ?
主题: React
难度: ⭐⭐⭐
问题:
const element = ( <h1 className="greeting"> Hello, world! </h1>)复制代码
上述代码如何应用 React.createElement
来实现:
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!');