乐趣区

关于react.js:2022前端React面试题-附答案

2022 前端社招 React 面试题 附答案

React 视频解说 点击学习

全副视频:点击学习

1. React-Router 的实现原理是什么?

客户端路由实现的思维:

  • 基于 hash 的路由:通过监听

    hashchange

事件,感知 hash 的变动

  • 扭转 hash 能够间接通过 location.hash=xxx
  • 基于 H5 history 路由:

    • 扭转 url 能够通过 history.pushState 和 resplaceState 等,会将 URL 压入堆栈,同时可能利用 history.go() 等 API
    • 监听 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.statethis.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!'
);
退出移动版