]kk前端全部面试题
86张脑图,一口气看完 React - 掘金
2019年17道高频React面试题及详解 - 掘金
https://blog.csdn.net/qq_40055200/article/details/104637574
React面试题
创建一个react项目
1.全局安装create-react-app
npm install -g create-react-app
2.创建项目
create-react-app myapp
3.局部安装,可以直接用npx
npx create-react-app myapp
4.进入文件夹
cd myapp
5.启用项目
npm start(开发模式下运行)
npm test(测试环境运行)
npm run build(打包为生产模式)
6.显示配置文件:不可逆的,只要显示了就没有任何方法再隐藏回去
npm run eject
这里需要等待一段时间,实际上会安装三个东西
1.React是什么?
用来构造用户界面的JS库
2.React有什么特点?(react的主要功能有哪些?)
它用于虚拟DOM,组件化设计模式,声明式代码,单向数据流,使用jsx描述信息等特点
3.什么是组件化设计模式?
可复用的代码可以抽成组件共同使用(UI,方法等)
4.声明式代码(编程)思想:
就是说明下你的目的,然后具体不说明怎么去做。
举例子:去酒吧告诉服务员你要一杯鸡尾酒,服务员把做好的鸡尾酒给你,并没有说做的过程是怎样的
const toLowerCase = arr = arr.map(
value => value.toLowerCase();
)
5.还有其他的编程方式吗?
命令式编程:就是描述代码如何工作,告诉计算机一步步的执行,先做什么后做什么。
举例子:去酒吧点一杯酒,指挥服务员
从架子上取下一个玻璃杯
把杯子放在酒桶前
打开酒桶开关,直到酒杯杯满
把做好的鸡尾酒递给顾客
const toLowerCase = arr => {
const res = [];
for (let i = 0, len = arr.length; i < len; i++) {
res.push(arr[i].toLowerCase());
}
return res;
}
6.React事件处理的几种方法(如何创建一个事件)
import React from 'react'
class Test extends React.Component{
handleClick2(){
console.log('click2')
}
hangleClick4 = () =>{
console.log('click4')
}
render(){
return(
)
}
}
export default Test
66.介绍Redux数据流的流程 (重要)
Redux如何实现多个组件之间的通信,多个组件使用相同状态如何进行管理
redux是js状态容器
工作流程:
Redux——详解_Mr.指尖舞者的博客-CSDN博客_redux
Redux原理及工作流程_QcoY_的博客-CSDN博客_redux工作流程
67.Hooks常用的
useEffct使用:
如果不传参数:相当于render之后就会执行
传参数为空数组:相当于componentDidMount
如果传数组:相当于componentDidUpdate
如果里面返回:相当于componentWillUnmount
会在组件卸载的时候执行清除操作。effect 在每次渲染的时候都会执行。React 会在执行当前 effect 之前对上一个 effect 进行清除。
useLayoutEffect:
useLayoutEffect在浏览器渲染前执行
useEffect在浏览器渲染之后执行
当父组件引入子组件以及在更新某一个值的状态的时候,往往会造成一些不必要的浪费,
而useMemo和useCallback的出现就是为了减少这种浪费,提高组件的性能,
不同点是:useMemo返回的是一个缓存的值,即memoized 值,而useCallback返回的是一个memoized 回调函数。
useCallback
父组件更新子组件会渲染,针对方法不重复执行,包装函数返回函数;
useMemo:
const memoizedValue =useMemo(callback,array)
callback是一个函数用于处理逻辑
array 控制useMemo重新执⾏行的数组,array改变时才会 重新执行useMemo
不传数组,每次更新都会重新计算
空数组,只会计算一次
依赖对应的值,当对应的值发生变化时,才会重新计算(可以依赖另外一个 useMemo 返回的值)
不能在useMemo⾥面写副作⽤逻辑处理,副作用的逻辑处理放在 useEffect内进行处理
自定义hook
自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook,
自定义 Hook 是一种自然遵循 Hook 设计的约定,而并不是 React 的特性
在我看来,自定义hook就是把一块业务逻辑单独拿出去写。
const [counter, setCounter] = useState(0);
const counterRef = useRef(counter); // 可以保存上一次的变量
useRef 获取节点
function App() {
const inputRef = useRef(null);
return
}
7.什么是单向数据流
数据主要从父节点传到子节点(通过props),如果父级的某个props改变了,React会重新渲染所有子节点
若子组件想要改版父子组件的值应该如果去做呢?
如下:event事件,子组件是不能够在自己的组件中去修改父组件的值,所以子组件中可以通过调用父组件的方法在父组件的方法中修改父组件的值
// 父组件
import React, {Component} from 'react'
import Child from './Child'
class Parent extends Component{
// 初始化
constructor(props){
super(props)
this.state = {
message: '我是从父组件传过来的'
}
}
handleUpdate = () =>{
this.setState({
message: '子组件修改父组件的值'
})
}
// 渲染
render(){
return(
)
}
}
export default Parent
// 子组件
import React, {Component} from 'react'
class Child extends Component{
// 初始化
constructor(props){
super(props)
}
// 渲染
render(){
return(
{this.props.message}
)
}
}
export default Child
8.什么是JSX呢?JSX代码到显示内容的转换过程
JSX就是JS的扩展语言(jsx语法= js语法+xml(html)语法)
是JS的语法扩展,本质上是JS对象。JSX可以很好的描述UI信息,但是浏览器无法直接读取,编译过程中会将JSX转换成JS的语法。
render(){
return(
Hello World from Edureka!!
);
}
9.react的优缺点
优点:
缺点:
每次 state
更改,render
函数都要生成完整的虚拟 DOM. 哪怕 state
改动很小,render
函数也会完整计算一遍。如果 render
函数很复杂,这个过程就白白浪费了很多计算资源
react 缺点_不玩微博的jason2的博客-CSDN博客_react缺点
10.VUE与React两个框架的区别对比
相似之处:
不同点 :
react使用的是js
11.React的工作原理
React会创建一个虚拟的DOM。当一个组件的状态改变时,React首先会通过“diffing"算法来标记虚拟DOM中的改变,第二步是调节,会用diff的结果来更新DOM.
12.阻止React的默认行为
e.preventDefault(),e是第三方提供的一个合成事件(注意:不能用return)
class App extends React.component{
constructor(props){
super(props);
this.state = {
}
}
hander(e){
e.preventDefault()
}
render(){
return
}
}
13.向事件处理程序传递参数
例如删除当前行的ID
14.React中key作用是什么?
主要用于列表中元素被修改,删除或添加的标识。在diff算法中,key用来判断该元素节点是被删除还是创建减少不必要的元素重复渲染。
15.React中diff算法
作用:用来计算VirtualDOM中被改变部分,针对该部分进行原生DOM操作,不用重新渲染整个页面
深入理解React虚拟DOM - 110255 - 博客园
16.props和state
state是局部的,除了它所在的这个组件其它组件都无法访问
17.React可以用两种方法声明组件,他们的区别是什么,什么情况你会选择哪一种?
区别:
// 函数组件
function Welcome(props){
return (
hello world
)
}
// 类组件:es6的加入让js直接支持使用class来定义类,react创建组件的方式是使用继承,官网推荐这种
// 使用方式,使用es6标准语法来构建
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component{
render(){
return (
欢迎进入react组件
)
}
}
ReactDOM.render(
,document.getElementById('root')
)
18.React组件生命周期的阶段是什么?
componentWillReceiveProps:
这个周期函数作用于特定的 prop 改变导致的 state 转换shouldComponentUpdate:
用来做性能优化,根据特定条件返回 true 或 false。如果你希望更新组件,请返回true 否则返回 false。默认情况下,它返回 false。componentWillUpdate:
数据在改变之前执行componentDidUpdate:
渲染发生后立即调用componentWillUnmount:
从 DOM 卸载组件后调用。用于清理内存空间class Timer extends React.Component {
constructor(props) {
super(props)
this.state = {seconds: 0}
}
tick(){
this.setState(state =>({
seconds: state.seconds + 1
}))
}
componentDidMount() {
this.interval = setInterval(() => this.tick(),1000)
}
componentWillMount(){
clearInterval(this.interval);
}
render() {
return (
Seconds: {this.state.seconds}
)
}
}
在react17 会删除以下三个生命周期
componentWillMount,componentWillReceiveProps , componentWillUpdate
19.什么是单向数据流和状态提升
举例子:如果两个组件都需要用到对方的状态,那么这时候就可以用到状态提升。具体做法是把两个子组件的状态写到他们的父组件中,然后父组件把状态传递给子组件的props中去,这样子组件也相当于有状态。
父组件
import React from "react"
import Child1 from "./child1"
import Child2 from "./child2"
export default class Parent extends React.Component {
constructor() {
super()
this.state = {
money: 1
}
}
changeHander(e){
this.setState({
money: e.target.value
})
}
render() {
return (
Parent
人民比:
美金:
)
}
}
子组件1
import React from "react"
export default class Child1 extends React.Component{
constructor(){
super()
this.state = {
input1: 0
}
}
componentDidMount(){
this.setState({
input1: this.props.money
})
}
changeHander(e) {
this.setState({
input1: e.target.value
})
}
render() {
return(
{ this.props.money }
)
}
}
子组件2
import React from "react"
export default class Child2 extends React.Component{
constructor(){
super();
this.state = {
input2: 1
}
}
componentDidMount(){
this.setState({
input2: this.props.money * 7
})
}
changeHander(e) {
this.setState({
input2: e.target.value
})
}
render() {
return(
{ this.props.money * 7}
)
}
}
20.调用setState之后发生了什么
setState会进行状态更新
将传入的参数对象与组件当前状态合并,然后触发所谓的调和过程,经过调和过程,根据新的state,React元素会重新构建虚拟DOM,进行diff算法对比新旧虚拟DOM树的区别,进行视图更新,而不是全部渲染
setState 采用的任务队列机制,不会马上执行,而是加入队列,在下次事件循环是一次性执行
21.为什么建议传递给setState的参数是一个callback(回调函数)而不是一个对象
this.props和this.state的更新可能是异步的,不能依赖他们的值去计算下一个state
22.关于this绑定==组件绑定点击事件
// bind
// 1
hello
// 2
clicked(param,event){
console.log(param) //hello world
console.log(event.target.value) //按钮
}
render(){
return (
点击
)
}
// 2.在构造函数中默认绑定this(推荐)
this.handleClick = this.handleClick.bind(this)
// 3.使用箭头函数来处理,handleClick点击事件的方法
this.handleClick(e)}>Click me
23.setState第二个参数的作用
该函数会在setState函数调用完成并且组件开始重渲染的时候被调用,我们可以用该函数来监听渲染是否完成
24.(在构造函数中)调用 super(props) 的目的是什么
在super() 被调用之前,子类是不能使用 this 的,在 ES5 中,子类必须在 constructor 中调用 super()。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor
访问 this.props
25.什么是React 路由?
Router 用于定义多个路由,当用户定义特定的 URL 时,如果此 URL 与 Router 内定义的任何 “路由” 的路径匹配,则用户将重定向到该特定路由。
路由是根据不同的url地址展示不同的内容或页面
import React from 'react';
import { Switch, Route, BrowserRouter } from 'react-router-dom';
import Home from './views/Home'
export default class App extends React.Component{
// 初始化
constructor(props){
super(props);
this.state = {}
}
// 渲染
render(){
return(
)
}
}
26. 区分Real DOM和Virtual DOM
Real DOM | Virtual DOM |
1.更新缓慢 | 1.更新更快 |
2.可以直接更新HTML | 2.无法直接更新HTML |
3.如果元素更新,则创建新DOM | 3.如果元素更新,则更新JSX |
4.DOM操作代价很高 | 4.DOM操作很简单 |
5.消耗的内存较多 | 5.很少消耗内存 |
27.为什么浏览器无法读取JSX?
浏览器只能处理JS对象,而不能读取常规的JSX。为了使浏览器能够读取JSX,首先,需要像Babel这样的JSX转换器将JSX转换为JS对象,然后再传给浏览器
28.你理解“在React中,一切都是组件”这句话。
组件是React应用UI的构建块。这些组件将整个UI分成小的独立并可重用的部分。每个组件彼此独立,而不会影响UI的其余部分
29.解释 React 中 render() 的目的。
接收数据和返回展示的内容
class HelloMessage extends React.Component {
render() {
return (
Hello {this.props.name}
);
}
}
ReactDOM.render(
,
document.getElementById('hello-example')
);
30.什么是 Props?
只读组件,必须保持纯函数,即不可变。它们总是再整个应用中从父组件传递到子组件。子组件永远不能将prop送回到父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据
31.React中的状态是什么?它是如何使用的?
是React 组件的核心,是数据的来源,必须尽可能简单。基本上状态是确定组件呈现和行为的对象。与props不同,它们是可变的,并创建动态和交互式组件。可以通过this.state()访问它们。
32.区分状态和 props
条件 | State | Props |
1.从父组件中接收初始值 | Y | Y |
2.父组件可以改变值 | N | Y |
3.在组件中设置默认值 | Y | Y |
4.在组件的内部变化 | Y | N |
5.设置子组件的初始值 | Y | Y |
6.在子组件的内部更改 | N | Y |
33.如何更新组件的状态?
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')
);
class App extends React.Component{
constructor(props);
this.state={
count:1
title:'数字计算'
}
}
handleClick=()=>{
this.replaceState({
count:this.state.count+1
})
}
render(){
return(
点我
)
}
}
count:1
34.React 中的箭头函数是什么?怎么用?
用于编写函数表达式的简短语法。这些函数允许正确绑定组件的上下文,因为在ES6中默认下不能使用自动绑定。使用高阶函数时,箭头函数非常有用
//General way
render() {
return(
);
}
//With Arrow Function
render() {
return(
this.handleOnChange(e) } />
);
}
35.区分有状态和无状态组件。
有状态组件 | 无状态组件 |
1.在内存中存储有关组件状态变化的信息 | 1.计算组件的内部状态 |
2.有权改变状态 | 2. 无权改变状态 |
3. 包含过去、现在和未来可能的状态变化情况 | 3. 不包含过去,现在和未来可能发生的状态变化情况 |
4. 接受无状态组件状态变化要求的通知,然后将 props 发送给他们。 | 4.从有状态组件接收 props 并将其视为回调函数。 |
40.React中的事件是什么?
在 React 中,事件是对鼠标悬停、鼠标单击、按键等特定操作的触发反应。处理这些事件类似于处理 DOM 元素中的事件。但是有一些语法差异,如:
事件参数重包含一组特定于事件的属性。每个事件类型都包含自己的属性和行为,只能通过其事件处理程序访问。
41.React中的合成事件是什么?
围绕浏览器原生事件充当跨浏览器对象。将不同浏览器的行为合并为一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性
42.如何创建refs?
import React from 'react'
class test extends React.Component{
state = {
myTest: 'jjj'
}
testRef = React.createRef() // 创建的是一个对象
render(){
return(
{
console.log("获取输入框中的值",this.testRefs.current.value)
console.log(this.testRefs.current, '是一个对象,可以获取到DOM')
}}>点我
)
}
}
export default test
43.列出一些应该使用 Refs 的情况。
通过ref来获取DOM元
//标签中设置ref,值为字符串
//函数中通过ref获取DOM中的值
getInputValue(){
cnosole.log(this.refs.name.value) //打印出input中输入的内容
}
class ReferenceDemo extends React.Component{
display() {
const name = this.inputDemo.value;
document.getElementById('disp').innerHTML = name;
}
render() {
return(
Name: this.inputDemo = input} />
Click
Hello !!!
);
}
}
43.如何模块化 React 中的代码?
可以使用 export 和 import 属性来模块化代码。它们有助于在不同的文件中单独编写组件。
//ChildComponent.jsx
export default class ChildComponent extends React.Component {
render() {
return(
This is a child component
);
}
}
//ParentComponent.jsx
import ChildComponent from './childcomponent.js';
class ParentComponent extends React.Component {
render() {
return(
);
}
}
44.解释react中render()的目的
每个React组件强制要求必须有一个render().它返回一个React元素,是原生DOM组件的表示。如果需要渲染多个HTML元素,则必须将它们组合在一个封闭标记内,例如