前端react常见面试题目(basic)
1. 如果 React 组件的属性没有传值,它的默认值是什么?
如果一个 React 组件的属性(props)没有传值,那么它的默认值会是 undefined
。你可以通过组件内部的逻辑来设置默认值,比如使用逻辑运算符或者 ES6 的默认参数。
jsx复制代码
const MyComponent = ({ prop = 'default value' }) => ( | |
<div>{prop}</div> | |
); |
2. React 中除了在构造函数中绑定 this,还有其他绑定 this 的方式么?
是的,还有其他几种绑定 this
的方式:
- 箭头函数:在构造函数、生命周期方法或事件处理程序中,使用箭头函数来自动绑定
this
。 - 在类属性中绑定:使用类属性语法(class properties)在声明时绑定
this
。 - 在 render 方法中绑定:虽然不推荐,但你可以在
render
方法中绑定this
,因为每次调用render
都会重新绑定,效率较低。 - 在事件处理器中绑定:在 JSX 中直接绑定事件处理器时,可以使用箭头函数。
jsx复制代码
class MyComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
this.handleClick = this.handleClick.bind(this); // 构造函数绑定 | |
} | |
handleClick = () => { // 类属性绑定 | |
console.log(this); | |
} | |
render() { | |
return ( | |
<button onClick={() => this.handleClick()}>Click</button> // 箭头函数绑定 | |
); | |
} | |
} |
3. 如何在 React 中引入其他 UI库,比如 tailwind?
在 React 项目中引入 Tailwind CSS 非常简单。你可以通过以下步骤实现:
- 安装 Tailwind CSS:使用 npm 或 yarn 安装 Tailwind CSS 和所需的 PostCSS 插件。
- 配置 Tailwind CSS:在项目的根目录下创建一个
tailwind.config.js
文件,并在postcss.config.js
中配置 Tailwind。 - 引入 Tailwind 样式:在你的主 CSS 文件(如
src/index.css
)中引入 Tailwind 的基础样式。
bash复制代码
npm install tailwindcss postcss autoprefixer | |
npx tailwindcss init -p |
然后在 src/index.css
中添加:
css复制代码
@tailwind base; | |
@tailwind components; | |
@tailwind utilities; |
4. 为什么在 React 中遍历时不建议使用索引作为唯一的 key 值?
在 React 中,使用 key
属性可以帮助 React 识别哪些元素发生了变化、被添加或被移除。如果列表项的 key
值不稳定或重复,React 可能会错误地重新渲染组件,导致性能问题和潜在的组件状态丢失。因此,建议使用唯一标识符(如 ID)作为 key
值,而不是数组的索引。
5. React Router 中的 Router 组件有几种类型?
React Router 提供了几种不同类型的 Router
组件,用于不同的环境:
- BrowserRouter:用于在客户端渲染的应用,使用 HTML5 的
history
API(如pushState
,replaceState
和popstate
事件)来保持 UI 和 URL 的同步。 - HashRouter:使用 URL 的 hash 部分(如
window.location.hash
)来保持 UI 和 URL 的同步。适用于不支持history
API 的旧浏览器。 - MemoryRouter:主要用于测试环境,它会将历史记录保存在内存中。
- StaticRouter:用于服务器端渲染,它接受一个
location
属性来渲染 UI。
6. React 的 constructor 和 getInitialState 有什么区别?
在 React 类组件中,constructor
是一个构造函数,用于初始化组件的状态和绑定方法。而 getInitialState
是 React 早期版本(0.13 之前)中用于初始化状态的方法,但在 React 0.13 及以后的版本中已经被废弃。现代 React 使用 constructor
和 state
属性来初始化状态。
7. 在 React 的 render 函数中,是否可以直接写 if else 判断?为什么?
是的,你可以在 render
函数中直接写 if-else
判断。然而,直接在 JSX 中使用 if-else
语句会导致语法错误,因为 JSX 期望一个表达式。你应该使用逻辑运算符(如 &&
或 ? :
)或者将条件逻辑放在变量中。
jsx复制代码
render() { | |
const isLoggedIn = this.state.isLoggedIn; | |
return ( | |
<div> | |
{isLoggedIn ? <LoggedInComponent /> : <LoginComponent />} | |
</div> | |
); | |
} |
8. 如何在 React 项目中引入图片?哪种方式更好?
在 React 项目中引入图片有几种方式:
- 直接通过 import:使用 ES6 的
import
语法将图片导入为模块。 - 通过 require:使用 CommonJS 的
require
语法。 - 通过 public 文件夹:将图片放在
public
文件夹中,并使用相对路径引用。
推荐使用 import
语法,因为它更符合现代 JavaScript 的模块系统,并且可以提供更好的类型检查和代码提示。
9. 在 React 的 JSX 中,属性是否可以被覆盖?覆盖的原则是什么?
在 JSX 中,属性可以被覆盖。当相同的属性被多次传递时,后面的值会覆盖前面的值。覆盖的原则是:后面的属性值会覆盖前面的属性值。
jsx复制代码
<MyComponent prop1="value1" prop1="value2" /> | |
// 在 MyComponent 中,prop1 的值将是 "value2" |
10. 在 React 中,如何操作虚拟 DOM 的 class 属性?
在 React 中,你应该使用 className
属性而不是 class
属性来指定元素的类名。这是因为 JSX 编译为 JavaScript 对象字面量,而 class
是 JavaScript 的保留字。
jsx复制代码
<div className="my-class">Hello World</div> |
11. 如何在 React 中创建一个事件?
在 React 中,你可以通过 JSX 语法直接在元素上添加事件处理器。事件处理器的名称应该采用驼峰命名法,并且以 on
开头,后跟事件名称(如 onClick
)。
jsx复制代码
<button onClick={this.handleClick}>Click Me</button> |
12. 什么是 React 中的受控组件?它的应用场景是什么?
受控组件是指其值由 React 组件的 state
控制的输入表单元素(如 <input>
, <select>
, <textarea>
)。这意味着表单数据由 React 组件管理,并且只能通过更新组件的 state
来改变。
应用场景包括需要验证用户输入、自动格式化用户输入或实时更新 UI 以反映表单状态的情况。
13. React 中的 mixins 有什么作用?适用于什么场景?
Mixins 在 React 早期版本中用于实现跨组件的代码复用。然而,Mixins 已经被认为是一种不推荐的模式,因为它们会导致代码难以理解和维护。现代 React 推荐使用高阶组件(HOC)、自定义 Hook 或渲染属性(Render Props)来实现代码复用。
14. 在 React Router 的 history 模式中,push 和 replace 方法有什么区别?
在 React Router 的 history
对象中,push
和 replace
方法都用于导航到新位置,但它们的行为有所不同:
- push:将新位置添加到历史堆栈中。用户可以通过点击浏览器的后退按钮回到上一个位置。
- replace:用新位置替换当前位置。用户无法通过点击浏览器的后退按钮回到上一个位置。
15. React 的 render 函数在什么情况下会被触发?
React 的 render
函数会在以下情况下被触发:
- 初始渲染时。
- 组件的
state
发生变化时。 - 组件接收到的
props
发生变化时。 - 父组件重新渲染时(即使
props
没有变化,如果父组件的render
方法被调用,子组件的render
方法也可能被调用)。
16. React 15 和 React 16 对 |E 的支持版本分别是什么?
这个问题可能是指 React 15 和 React 16 对某些特性或 API 的支持情况。不过,|E
并不是一个明确的 React 术语或特性。一般来说,React 16 引入了许多重要的改进,如错误边界(Error Boundaries)、Fragments 和更高效的渲染机制(如 Fiber)。React 15 没有这些特性。
17. 为什么浏览器不能直接解析 React 的 JSX?怎么解决!
浏览器无法直接解析 JSX,因为 JSX 是一种语法扩展,它允许你在 JavaScript 代码中写类似 HTML 的标记。JSX 需要在构建过程中被转译为普通的 JavaScript 代码。这通常通过 Babel 这样的工具来实现。
要解决这个问题,你需要在项目中配置 Babel,并确保它能够将 JSX 转译为浏览器可以理解的 JavaScript 代码。
18. React 事件绑定的方式有哪些? 每种方式有什么区别?
在 React 中,事件绑定主要有两种方式:通过 JSX 中的属性绑定和在构造函数或类方法中绑定。
方式一:通过 JSX 中的属性绑定
这是最常见的方式,直接在 JSX 中使用 onEvent
(如 onClick
、onChange
等)属性绑定事件处理函数。
jsx复制代码
class MyComponent extends React.Component { | |
handleClick = () => { | |
console.log('Button clicked!'); | |
} | |
render() { | |
return <button onClick={this.handleClick}>Click Me</button>; | |
} | |
} |
或者,如果你使用的是函数组件,你可以直接使用箭头函数:
jsx复制代码
function MyComponent() { | |
const handleClick = () => { | |
console.log('Button clicked!'); | |
} | |
return <button onClick={handleClick}>Click Me</button>; | |
} |
方式二:在构造函数或类方法中绑定
在类组件中,你可以在构造函数中通过 this.methodName = this.methodName.bind(this)
来绑定事件处理函数,或者在类方法中使用 .bind(this)
。
jsx复制代码
class MyComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
this.handleClick = this.handleClick.bind(this); | |
} | |
handleClick() { | |
console.log('Button clicked!'); | |
} | |
render() { | |
return <button onClick={this.handleClick}>Click Me</button>; | |
} | |
} |
区别:
- JSX 中绑定:这种方式通常更简洁,特别是在函数组件中。它利用了箭头函数的特性,自动绑定了
this
到当前组件实例。 - 构造函数中绑定:这种方式在类组件中很常见,尤其是在早期版本的 React 中。它需要在构造函数中显式绑定
this
,以确保在事件处理函数中能够正确访问组件的实例和方法。
19. 在 React 构造函数中调用 super(props)
的目的是什么?
在 React 类组件中,调用 super(props)
是必须的,特别是在构造函数中。其目的是确保 this.props
在构造函数中被正确初始化。
- 继承父类:
React.Component
是一个类,任何自定义的类组件都需要继承它。调用super()
是 JavaScript 中继承父类构造函数的标准做法。 - 初始化
props
:通过传递props
给super()
,React 能够确保this.props
在类的构造函数中被正确设置。这样,你就可以在构造函数中安全地访问this.props
。
jsx复制代码
class MyComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
// 现在可以安全地访问 this.props | |
console.log(this.props); | |
} | |
render() { | |
return <div>Hello, World!</div>; | |
} | |
} |
20. 使用 create-react-app
创建新应用时,如果遇到卡顿的问题,如何解决?
使用 create-react-app
创建新应用时,如果遇到卡顿的问题,可以尝试以下几种解决方法:
-
检查网络连接:确保你的网络连接稳定,因为
create-react-app
需要从 npm 或 yarn 下载依赖包。 -
使用不同的包管理器:如果你默认使用的是 npm,可以尝试使用 yarn 来创建项目,反之亦然。有时候,不同的包管理器在处理依赖时有不同的性能表现。
-
增加内存限制:如果是因为内存不足导致的卡顿,可以尝试增加 Node.js 的内存限制。例如,在运行
create-react-app
命令前,可以设置环境变量NODE_OPTIONS
来增加内存:bash复制代码
export NODE_OPTIONS=--max_old_space_size=4096
npx create-react-app my-app
-
使用 VPN 或更换 npm 源:如果你在中国大陆地区,可能会因为 npm 源的问题导致下载速度缓慢。你可以尝试使用 VPN 或切换到淘宝的 npm 镜像源来加速下载。
-
清理 npm 缓存:有时候,清理 npm 的缓存可以解决一些奇怪的问题。你可以运行
npm cache clean --force
来清理缓存。
21. 在 React 的 JSX 中如何写注释?
在 React 的 JSX 中,你可以使用 JavaScript 的多行注释(/* ... */
)或单行注释(// ...
)来添加注释。但是,需要注意的是,单行注释不能放在 JSX 标签的同一行内,否则会导致编译错误。
jsx复制代码
// 这是一个单行注释,可以放在 JSX 标签的上方或下方 | |
const MyComponent = () => { | |
/* | |
这是一个多行注释, | |
可以跨越多行。 | |
*/ | |
return ( | |
<div> | |
{/* 这是一个内联注释,用于解释下面的 JSX */} | |
<h1>Hello, World!</h1> | |
</div> | |
); | |
} |
22. React 中 Component
和 PureComponent
有什么区别?
React.Component
和 React.PureComponent
都是 React 中用于创建类组件的基类,但它们有一些关键的区别:
-
React.Component
:这是 React 中最基本的组件基类。它不会对你的组件进行任何特殊的优化。每次组件的状态(state
)或属性(props
)发生变化时,它都会重新渲染。 -
React.PureComponent
:这个基类与React.Component
非常相似,但它对组件的性能进行了优化。它通过浅比较(shallow comparison)来检查props
和state
是否发生了变化。如果它们没有变化(即引用没有改变),那么组件就不会重新渲染。这对于避免不必要的渲染和提高性能非常有用。但是,需要注意的是,浅比较只检查对象的第一层属性,如果属性是嵌套对象或数组,那么PureComponent
可能无法正确检测到变化。
23. React 项目如何将多个组件嵌入到一个组件中?
在 React 项目中,你可以通过 JSX 将多个组件嵌入到一个组件中。这是 React 组件化的核心思想之一,允许你构建可重用和可组合的组件。
jsx复制代码
// 定义子组件 | |
const Header = () => <header>This is the header</header>; | |
const Content = () => <main>This is the content</main>; | |
const Footer = () => <footer>This is the footer</footer>; | |
// 定义父组件,将多个子组件嵌入其中 | |
const Layout = () => ( | |
<div> | |
<Header /> | |
<Content /> | |
<Footer /> | |
</div> | |
); | |
// 使用父组件 | |
const App = () => ( | |
<div> | |
<Layout /> | |
</div> | |
); | |
export default App; |
在这个例子中,Header
、Content
和 Footer
是三个子组件,它们被嵌入到 Layout
父组件中。然后,Layout
组件又被嵌入到 App
组件中。这样,你就可以通过组合不同的组件来构建复杂的用户界面。
24. 事件在 React 中是如何处理的?
在 React 中,事件处理是通过合成事件(SyntheticEvent)系统来实现的。React 会根据原生浏览器事件创建一个合成事件对象,这个对象兼容所有浏览器,并且具有与原生事件相同的属性和方法,但它在所有浏览器中表现一致。
事件处理函数通常作为 JSX 属性传递,例如 onClick
、onChange
等。这些函数可以定义在类组件的方法中,或者使用箭头函数在函数组件中定义。
jsx复制代码
class MyComponent extends React.Component { | |
handleClick = (event) => { | |
console.log(event); // 合成事件对象 | |
} | |
render() { | |
return <button onClick={this.handleClick}>Click Me</button>; | |
} | |
} | |
// 或者在函数组件中 | |
function MyFunctionComponent() { | |
const handleClick = (event) => { | |
console.log(event); // 合成事件对象 | |
} | |
return <button onClick={handleClick}>Click Me</button>; | |
} |
25. 如何在 React 项目中开启生产模式?
在 React 项目中,生产模式通常是通过构建工具(如 Create React App 的 react-scripts
)来开启的。在生产模式下,构建工具会进行代码优化,如代码拆分、压缩、去除开发时的警告和日志等,以提高应用的性能和减少包大小。
对于 Create React App 创建的项目,你可以通过运行 npm run build
或 yarn build
命令来生成生产模式的构建。这个命令会创建一个 build
文件夹,里面包含了优化后的代码,你可以将其部署到服务器上。
26. 在 React 中,是否可以在 render 方法中访问 refs?为什么?
在 React 中,你不应该在 render
方法中访问 refs
。refs
是用来访问 DOM 节点或 React 元素实例的,它们通常在组件挂载后(即在 componentDidMount
或 useEffect
钩子中)才可用。
在 render
方法中访问 refs
是不安全的,因为此时组件可能还没有完全挂载,refs
可能还没有被正确设置。此外,render
方法应该是一个纯函数,它只根据 props
和 state
来返回 UI 描述,而不应该产生任何副作用,包括访问 refs
。
27. 在 React 中声明组件时,组件名的第一个字母是否必须是大写?为什么?
是的,在 React 中声明组件时,组件名的第一个字母必须是大写。这是为了区分 React 组件和 HTML 元素。例如,<MyComponent />
是一个 React 组件,而 <div />
是一个 HTML 元素。
这个约定有助于 JSX 解析器正确地识别组件和元素,并避免潜在的冲突。如果组件名的第一个字母不是大写,JSX 解析器可能会将其视为 HTML 标签,从而导致错误。
28. React 的类组件和函数式组件有什么区别?
React 的类组件和函数式组件是两种不同的组件定义方式,它们有以下主要区别:
- 定义方式:类组件使用 ES6 的类语法定义,而函数式组件则使用普通的 JavaScript 函数定义。
- 状态管理:类组件使用
this.state
和this.setState
来管理状态,而函数式组件则使用 React Hooks(如useState
)来管理状态。 - 生命周期方法:类组件具有生命周期方法(如
componentDidMount
、componentWillUnmount
等),而函数式组件则使用useEffect
和其他 Hooks 来处理副作用。 - 性能优化:函数式组件通常更容易进行性能优化,因为它们更容易被转换为纯函数,并且可以使用 React 的 Memoization 技术(如
React.memo
)来避免不必要的渲染。
29. React 的 render 函数返回的数据类型是什么?
React 的 render
函数(无论是类组件中的 render
方法还是函数组件中的返回值)必须返回一个有效的 React 元素(React Element)。这个元素可以是 DOM 元素(如 <div />
)、React 组件(无论是类组件还是函数组件)、数组或片段(React.Fragment
)、布尔值(null
、undefined
会被忽略并不渲染任何东西)、或者字符串(字符串会被包裹在一个 span
元素中)。
30. Redux 状态管理器与将变量挂载到 window 对象中有什么区别?
Redux 是一个用于管理应用状态的 JavaScript 库,它提供了一个可预测的状态容器,允许你以可预测的方式改变和访问应用的状态。相比之下,将变量挂载到 window
对象中是一种简单但不太优雅的状态管理方式。
- 可预测性:Redux 通过 action 和 reducer 的组合来确保状态的变化是可预测的。而
window
对象上的变量可以被任何脚本随时修改,这可能导致状态的不一致性。 - 可维护性:Redux 提供了强大的开发工具(如 Redux DevTools),可以帮助你调试和跟踪状态的变化。而
window
对象上的状态变化则更难跟踪和调试。 - 可扩展性:Redux 可以与 React、Angular、Vue 等多种前端框架集成,并且支持中间件和插件来扩展其功能。而
window
对象上的状态管理则缺乏这种可扩展性。 - 安全性:将敏感数据存储在
window
对象上可能会带来安全风险,因为任何能够访问页面的脚本都可以访问这些数据。而 Redux 可以通过中间件和 reducer 的逻辑来控制对状态的访问和修改。
31. React 的 state 和 setState 有什么区别?
在 React 中,state
是组件的私有数据,它决定了组件的渲染输出。setState
是一个用于更新组件状态的方法。
- state:它是一个对象,包含了组件的当前状态。在类组件中,你可以通过
this.state
来访问状态。在函数组件中,你不能直接访问状态,但你可以使用useState
Hook 来获取状态的值和更新状态的函数。 - setState:它是一个方法,用于更新组件的状态。当你调用
setState
并传入一个新的状态值时,React 会将其与当前的状态合并,并触发组件的重新渲染。在类组件中,你通过this.setState
来调用它。在函数组件中,你不能直接调用setState
,但你可以使用useState
Hook 返回的更新函数来更新状态。
32. React 的 JSX 和 HTML 有什么区别?
JSX 是 JavaScript XML 的缩写,它是一种 JavaScript 的语法扩展,允许你在 JavaScript 代码中写类似 HTML 的标签。JSX 最终会被编译成标准的 JavaScript 对象调用,这些对象描述了你想要渲染的 UI。
与 HTML 相比,JSX 有以下主要区别:
- 语法:JSX 允许你在标签中嵌入 JavaScript 表达式(使用
{}
),而 HTML 则不允许。 - 属性:在 JSX 中,所有的属性名都使用 camelCase(驼峰命名法),例如
className
而不是class
,htmlFor
而不是for
。这是为了与 JavaScript 的对象属性命名规则保持一致。 - 组件:JSX 允许你使用自定义的 React 组件,这些组件可以接收
props
并返回 UI 描述。而 HTML 只能使用标准的 HTML 元素。 - 编译:JSX 需要被编译成标准的 JavaScript 代码才能被浏览器执行。这通常是通过 Babel 这样的编译器来实现的。而 HTML 则不需要编译,它可以直接被浏览器解析和渲染。
33. 在 React 中,如何检验 props?为什么要验证 props?
在 React 中,你可以使用 propTypes
来验证 props
。propTypes
是一个从 prop-types
库中导入的对象,它提供了一套用于验证 props
类型和必要性的方法。
验证 props
的原因有以下几点:
- 类型安全:通过验证
props
的类型,你可以确保传递给组件的数据是正确的,这有助于避免运行时错误。 - 文档化:
propTypes
提供了组件的props
的文档说明,这有助于其他开发者理解如何使用你的组件。 - 调试:当
props
的类型不正确时,React 会在控制台中显示警告信息,这有助于你快速定位问题所在。
jsx复制代码
import React from 'react'; | |
import PropTypes from 'prop-types'; | |
class MyComponent extends React.Component { | |
render() { | |
return <div>{this.props.text}</div>; | |
} | |
} | |
MyComponent.propTypes = { | |
text: PropTypes.string.isRequired, | |
}; |
在这个例子中,MyComponent
组件有一个名为 text
的 prop
,它必须是字符串类型,并且是必需的。如果传递给 MyComponent
的 text
不是字符串类型,或者没有提供 text
,React 会在控制台中显示警告信息。
34. 如何在 React Jsx 中实现 for 循环?
在 JSX 中,你不能直接使用 JavaScript 的 for
循环,因为 JSX 本质上是 JavaScript 对象,而不是 HTML 标记。但是,你可以使用 JavaScript 的数组方法来生成 JSX 元素数组,或者使用 map
方法来遍历数组并返回 JSX 元素。
jsx复制代码
function MyComponent({ items }) { | |
return ( | |
<ul> | |
{items.map((item, index) => ( | |
<li key={index}>{item}</li> | |
))} | |
</ul> | |
); | |
} | |
// 使用组件 | |
<MyComponent items={['Item 1', 'Item 2 |
35. React 组件推荐的命名规范是什么? 为什么不推荐使用 displayName
?
推荐命名规范:
- PascalCase (大驼峰命名法): 对于 React 组件,推荐使用 PascalCase 进行命名,例如
MyComponent
。这有助于在 JSX 中区分组件和普通的 HTML 标签。 - 文件名与组件名一致: 组件的文件名应与组件名保持一致,例如
MyComponent.jsx
。
不推荐使用 displayName
的原因:
displayName
主要是用于调试和开发工具中显示更友好的组件名称,而不是用于生产环境。- 依赖
displayName
来做逻辑判断或功能实现是不推荐的,因为displayName
可以被随意修改,不具备唯一性和可靠性。
36. 在 React 项目中,如何使用字体图标?
可以使用诸如 Font Awesome、Material Icons 等字体图标库。以下是一个使用 Font Awesome 的示例:
-
安装 Font Awesome:
bash复制代码
npm install --save @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-fontawesome
-
在项目中使用:
jsx复制代码
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';
const MyComponent = () => (
<div>
<h1>Hello, world!</h1>
<FontAwesomeIcon icon={faCoffee} />
</div>
);
export default MyComponent;
37. 在 React 的 JSX 中,如何使用自定义属性?
在 JSX 中,可以传递自定义属性(也称为 props)给组件。例如:
jsx复制代码
const MyComponent = (props) => ( | |
<div> | |
<h1>{props.title}</h1> | |
<p>{props.description}</p> | |
<input type="text" value={props.initialValue} onChange={props.handleChange} /> | |
</div> | |
); | |
// 使用 MyComponent 时传递自定义属性 | |
<MyComponent title="My Title" description="This is a description" initialValue="Hello" handleChange={(e) => console.log(e.target.value)} /> |
38. 在 React Router 中如何获取 URL 参数?
在 React Router v6 中,可以使用 useParams
钩子来获取 URL 参数。例如:
jsx复制代码
import React from 'react'; | |
import { useParams } from 'react-router-dom'; | |
const UserProfile = () => { | |
const { userId } = useParams(); | |
return ( | |
<div> | |
<h1>User Profile: {userId}</h1> | |
</div> | |
); | |
}; | |
// 在路由配置中 | |
<Route path="user/:userId" element={<UserProfile />} /> |
39. React 的 getInitialState
方法有什么作用?
getInitialState
是类组件中用于定义组件初始状态的方法,但在 React 的最新版本中,推荐使用构造函数(constructor)和 state
属性来初始化状态。例如:
jsx复制代码
class MyComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
count: 0 | |
}; | |
} | |
render() { | |
return ( | |
<div> | |
<p>Count: {this.state.count}</p> | |
</div> | |
); | |
} | |
} |
40. 使用 React 进行开发的方式有哪些?
- 类组件(Class Components): 使用 ES6 类语法定义组件。
- 函数组件(Functional Components): 使用函数定义组件,通常与 Hooks 一起使用。
- Hooks: 在函数组件中使用状态和其他 React 特性。
- 高阶组件(Higher-Order Components, HOCs): 用于复用组件逻辑的高级技术。
- Render Props: 用于在组件之间共享逻辑的一种技术。
41. React
的 props.children.map
和普通的 .map
有什么区别? 为什么优先选择 React
的 map
?
props.children.map
是对 React 的children
(一个特殊的 prop,可以包含多个子元素)进行遍历。- 普通的
.map
是 JavaScript 数组的方法,用于遍历数组。
优先选择 props.children.map
是因为:
- 当处理
props.children
时,它可能包含多个子元素,而不仅仅是数组。使用React.Children.map
可以安全地处理props.children
,无论是单个元素、数组还是null
。
jsx复制代码
import React from 'react'; | |
const MyComponent = ({ children }) => ( | |
<div> | |
{React.Children.map(children, child => ( | |
<div>{child}</div> | |
))} | |
</div> | |
); |
42. React
的 createClass
是怎么实现的?
React.createClass
是 React 类组件的一种定义方式,但在 React v16.8 之后被推荐使用 class
语法代替。React.createClass
内部是一个工厂函数,它接受一个对象,并返回一个 React 组件类。这个对象定义了组件的 render
方法、getInitialState
方法、生命周期方法等。
jsx复制代码
const MyComponent = React.createClass({ | |
getInitialState() { | |
return { | |
count: 0 | |
}; | |
}, | |
handleClick() { | |
this.setState({ count: this.state.count + 1 }); | |
}, | |
render() { | |
return ( | |
<div> | |
<p>Count: {this.state.count}</p> | |
<button onClick={this.handleClick}>Increment</button> | |
</div> | |
); | |
} | |
}); |
43. React
的 createElement
和 cloneElement
有什么区别?
createElement(type, [props], [...children])
: 创建一个新的 React 元素。type
是字符串(表示 HTML 标签)或 ReactClass(表示组件)。cloneElement(element, [props], [...children])
: 克隆并返回一个新的 React 元素,新元素将拥有新的 props 和/或 children。element
是要克隆的 React 元素。
jsx复制代码
const element = React.createElement('div', { className: 'container' }, 'Hello'); | |
const clonedElement = React.cloneElement(element, { id: 'unique-id' }, 'World'); |
44. React
项目中,什么时候使用箭头函数会更方便?
- 在类组件的方法中: 为了确保
this
指向类实例,可以使用箭头函数来定义方法,但这通常不推荐,因为会影响性能(每次渲染都会创建新的函数)。 - 在函数组件和 Hooks 中: 箭头函数非常适合在函数组件和自定义 Hooks 中使用,因为它们可以捕获当前的上下文(如闭包)。
jsx复制代码
const MyComponent = () => { | |
const handleClick = () => { | |
console.log('Button clicked'); | |
}; | |
return <button onClick={handleClick}>Click me</button>; | |
}; |
45. 什么是 React
中的非受控组件? 它的应用场景是什么?
非受控组件是指那些不由 React 控制其值的组件,即其值由 DOM 本身管理,而不是由 React 的 state 管理。
应用场景:
- 表单元素(如
<input type="file">
)通常是非受控的,因为文件输入只能通过用户交互来触发。 - 在某些情况下,如果不需要在组件的 state 中管理表单值,可以使用非受控组件来简化代码。
jsx复制代码
const MyForm = () => { | |
const handleSubmit = (e) => { | |
e.preventDefault(); | |
const inputValue = e.target.elements.myInput.value; | |
console.log(inputValue); | |
}; | |
return ( | |
<form onSubmit={handleSubmit}> | |
<input type="text" name="myInput" /> | |
<button type="submit">Submit</button> | |
</form> | |
); | |
}; |
46. 在 React
中,如何将参数传递给事件处理函数?
可以通过箭头函数或在事件处理函数中直接传递参数。
jsx复制代码
const MyComponent = () => { | |
const handleClick = (param) => { | |
console.log(param); | |
}; | |
return ( | |
<div> | |
<button onClick={() => handleClick('Button 1 clicked')}>Button 1</button> | |
<button onClick={(e) => handleClick('Button 2 clicked', e)}>Button 2</button> | |
</div> | |
); | |
}; |
相关文章:

前端react常见面试题目(basic)
1. 如果 React 组件的属性没有传值,它的默认值是什么? 如果一个 React 组件的属性(props)没有传值,那么它的默认值会是 undefined。你可以通过组件内部的逻辑来设置默认值,比如使用逻辑运算符或者 ES6 的默认参数。 …...

机器人技术基础(4章逆运动解算和雅克比矩阵)
逆运动解算: 雅克比矩阵: 将动力学分析转向运动的物体 下图中的 n o y 反映了机器人的姿态矩阵, 最后一列 p 反应了机器人在空间中的位置:...

OpenGL入门002——顶点着色器和片段着色器
文章目录 一些概念坐标转换阶段顶点着色器片段着色器VBOVAO 实战简介main.cppCMakeLists.txt最终效果 一些概念 坐标转换阶段 概述: 模型空间、世界空间、视图空间和裁剪空间是对象在3D场景中经历的不同坐标变换阶段。每个空间对应渲染管道的一个步骤,…...

[数组排序] LCR 164. 破解闯关密码
文章目录 1. 题目链接2. 题目大意3. 示例4. 解题思路5. 参考代码 1. 题目链接 LCR 164. 破解闯关密码 - 力扣(LeetCode) 2. 题目大意 描述:给定一个非负整数数组 nums。 要求:将数组中的数字拼接起来排成一个数,打印…...

05 Django 框架模型介绍(一)
文章目录 1、Django 模型简介2、Django 中创建并使用模型(1)新加一个名为 myapp 的应用(2)定义模型类(2)激活模型类(3)创建数据库迁移文件(4)应用迁移文件 3、…...

【简道云 -注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

【C++题解】1970. 判断是什么字符
欢迎关注本专栏《C从零基础到信奥赛入门级(CSP-J)》 问题:1970. 判断是什么字符 类型:字符串、字符型 题目描述: 从键盘读入一个字符,有可能是大写字母、小写字母、数字中的一种,请编程判断&…...

Python自动化操作Word文档详解
在日常办公和数据处理中,我们经常需要处理Word文档。手动操作Word文档可能会非常繁琐和耗时,而使用Python可以实现自动化操作,提高工作效率。本文将详细介绍如何使用Python自动化操作Word文档,包括读取、写入、修改和格式化等操作…...

常用滤波算法(二)-中位值滤波法
文章目录 一、中位值滤波法简介二、C语言实现中位值滤波法三、程序说明信号初始化:滤波窗口大小:内存分配:中位值滤波函数:中位值计算函数:内存释放: 四、总结 中位值滤波法,作为一种非线性滤波…...

HCIP--以太网交换安全(总实验)
实验背景 假如你是公司的网络管理员,为了提高公司网络安全性,你决定在接入交换机部署一些安全技术:端口隔、端口安全、DHCP snooping、IPSG。 实验拓扑图 实验的要求: 1.在R1、R2连接在GE0/0/1和GE0/0/2接口下,均划…...

C语言 | Leetcode C语言题解之第519题随机翻转矩阵
题目: 题解: typedef struct {unsigned long long val;UT_hash_handle hh; } Hash;typedef struct {Hash *hash;int n_rows;int n_cols; } Solution, SL;Solution* solutionCreate(int n_rows, int n_cols) {SL *obj malloc(sizeof(SL));obj->hash …...

《机器人SLAM导航核心技术与实战》第1季:第10章_其他SLAM系统
视频讲解 【第1季】10.第10章_其他SLAM系统-视频讲解 【第1季】10.1.第10章_其他SLAM系统_RTABMAP算法-视频讲解 【第1季】10.2.第10章_其他SLAM系统_VINS算法-视频讲解 【第1季】10.3.第10章_其他SLAM系统_机器学习与SLAM-视频讲解 第1季:第10章_其他SLAM系统 …...

《双指针篇》---快乐数
题目传送门 1.创建一个bitsum函数用于得到这个数每位的平方和。 2.令快指针等于bitsum(n) 3.慢指针等于n。 逐步令 fast bitSum(bitSum(fast)); slow bitSum(slow); 若最后fast等于slow,则且等于1.则return true。 否则return false。 cla…...

U盘引导丢失问题的处理办法
项目背景:在使用自制的u盘系统的时候经常遇到引导丢失的问题,那么咱们怎么解决这个问题呢,首先第一步通过手动引导u盘 进入系统,同时再进行引导区的修复这样u盘系统就可以正常工作了。 1 进入grub 的提示符下面,首先…...

layui tree customSelet选中的内容重写,查找父级
layui tree customSelet选中的内容重写,查找父级 需要重新源码 // 递归查找函数 // tree 所有数据 ,nodeId选中数据id值 function findParent(tree, nodeId, parent null) {for (let i 0; i < tree.length; i) {if (tree[i].id nodeId) {return …...

Maven 插件
Maven 插件 Maven 是一个强大的项目管理和构建自动化工具,广泛应用于 Java 项目中。它通过插件来实现各种功能,如编译、测试、打包、部署等。Maven 插件是 Maven 的核心组成部分,它们扩展了 Maven 的功能,使其能够执行各种任务。…...

MybatisPlus入门(七)MybatisPlus-DQL编程控制
一、查询投影 查询投影:查出来的东西有多少字段,设置查询出来的结果长什么样,查出的字段控制; 查询投影适用于lamda格式,使用select 查询 lqw.select(User::getId,User::getName,User::getAge); 代码示例࿱…...

K8S概念及其常见组件和整体架构
1.概念 什么是Kubernetes 官网:Kubernetes 文档 | Kubernetes K8S的本质是一组服务器集群,可以在对应服务器集群的每个节点上运行程序,来对节点中的容器进行管理 类似Master-Work方式,每个服务器上安装特定的K8S组件,…...

LabVIEW继电器视觉检测系统
随着制造业的自动化与高精度要求不断提升,传统的人工检测方法逐渐难以满足高效和高精度的需求。特别是在航空航天、医疗设备等高端领域,密封继电器推动杆部件的质量直接影响到设备的性能与可靠性。LabVIEW自动化视觉检测系统,能对推动杆部件进…...

linux操作系统进程
linux操作系统是对下的软硬件进行管理,为了能够对上提供稳定,快速,安全的服务而诞生的软件。 广义上的操作系统是包含搭载在操作系统上的软件和函数库等文件的。 狭义上的操作系统就是操作系统内核,进行进程管理,文件…...

jeecgbootvue2菜单路由配置静态文件夹(public)下的html
需求:想要在菜单配置src/assets/iconfont/chart.html显示页面(目的是打包上线以后运维依然可以修改数据) 官网没有相关数据:菜单配置说明 JeecgBoot 开发文档 看云 问题现象: 我把文件放在src/assets/iconfont/chart.html然后在vue中作为 iframe 的 src 属性&am…...

PHP反序列化原生类字符串逃逸框架反序列化利用
PHP反序列化 概念 序列化的原因:为了解决开发中数据传输和数据解析的一个情况(类似于要发送一个椅子快递,不可能整个椅子打包发送,这是非常不方便的,所以就要对椅子进行序列化处理,让椅子分成很多部分在一起打包发送…...

6.1、属性动画
使用显式动画产生布局更新动画 1.旋转动画 只修改对应的属性 rotate({angle: this.angle}) 即可达到效果 动画效果 对应实现代码 @Entry @Component struct AnimationPage {@State angle:number = 0aboutToAppear() {...

v-model还可以作用于其他表单元素的使用
1、文本输入框 直接双向绑定输入的元素值 初始化默认值为空字符串 2、复选按钮 直接双向绑定输入的元素值 初始化默认值为flase,不选中 3、单选按钮, 1.使用name分组,产生互斥效果。 2.使用value存值, 3再用v-model双向绑定…...

最短路的求解
实验类型:◆验证性实验 ◇综合性实验 ◇设计性实验 实验目的:学会使用Matlab求解最短路。 实验内容:1.熟练运用Floyd算法;2. 熟练运用Dijkstra算法;3.利用Matlab编程实现最短路的计算。 例1:已知无向图…...

四:java 基础知识(4)-- 异常 字符串
目录 1. 异常处理 1.1 什么是异常 1.2 异常的类型 1.2.1 检查异常 1.2.2 运行时异常 1.3 异常的捕获与处理 1.3.1 try-catch 语句 1.3.2 finally 块 1.3.3 throw 和 throws 关键字 1.4 自定义异常 1.5 异常的最佳实践 2. 字符串 2.1 String 类的概述 2.2 字符串的…...

Uniapp 实现app自动检测更新/自动更新功能
实现步骤 配置 manifest.json 在 manifest.json 中设置应用的基本信息,包括 versionName 和 versionCode。 一般默认0.0.1,1. 服务器端接口开发 提供一个 API 接口,返回应用的最新版本信息,版本号、下载链接。客户端检测更新 使…...

7.0、RIP
RIP (Routing Information Protocol) 简介 RIP是由Xerox在20世纪70年代开发的,最初定义在RFC1058中。RIP用两种数据包传输更新:更新和请求,每个有RIP功能的路由器在默认情况下,每隔30s利用UDP520端口向与它直连的网络邻居广播(RIP1)或组播(R…...

C#与C++结构体的交互
C#在和C进行交互时,有时候会需要传递结构体。 做一些总结,避免大家在用的时候踩坑。 一般情况 例如我们在C里定义了一个struct_basic结构体 1 struct struct_basic 2 { 3 WORD value_1; 4 LONG value_2; 5 DWORD value_3; 6 UINT v…...

sql纵表转横表
项目上有一个需求(例子): 用户表 user{ id, name, workCode } id name workCode 1 张三 WC1001 2 李四 WC1002 工作信息表 work{ id, name, workCode, workTimeSun } id name …...