StrictMode
是一个用来突出显示应用程序中潜在问题的工具。与 Fragment
一样,StrictMode
不会渲染任何可见的 UI。它为其后代元素触发额外的检查和警告。 可以为应用程序的任何部分启用严格模式。例如:
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
复制代码
在上述的示例中,不会对 Header
和 Footer
组件运行严格模式检查。但是,ComponentOne
和 ComponentTwo
以及它们的所有后代元素都将进行检查。
StrictMode
目前有助于:
前端react面试题详细解答
(1)遍历数组:map && forEach
import React from 'react';
class App extends React.Component {
render() {
let arr = ['a', 'b', 'c', 'd'];
return (
<ul>
{
arr.map((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
)
}
}
class App extends React.Component {
render() {
let arr = ['a', 'b', 'c', 'd'];
return (
<ul>
{
arr.forEach((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
)
}
}
复制代码
(2)遍历对象:map && for in
class App extends React.Component {
render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
<ul>
{
(() => {
let domArr = [];
for(const key in obj) {
if(obj.hasOwnProperty(key)) {
const value = obj[key]
domArr.push(<li key={key}>{value}</li>)
}
}
return domArr;
})()
}
</ul>
)
}
}
// Object.entries() 把对象转换成数组
class App extends React.Component {
render() {
let obj = {
a: 1,
b: 2,
c: 3
}
return (
<ul>
{
Object.entries(obj).map(([key, value], index) => { // item是一个数组,把item解构,写法是[key, value]
return <li key={key}>{value}</li>
})
}
</ul>
)
}
}
这个问题就设计到了数据持久化, 主要的实现方式有以下几种:
pushState
函数可以给历史记录关联一个任意的可序列化 state
,所以可以在路由 push
的时候将当前页面的一些信息存到 state
中,下次返回到这个页面的时候就能从 state
里面取出离开前的数据重新渲染。react-router 直接可以支持。这个方法适合一些需要临时存储的场景。React 并不强制要求使用 JSX。当不想在构建环境中配置有关 JSX 编译时,不在 React 中使用 JSX 会更加方便。
每个 JSX 元素只是调用 React.createElement(component, props, ...children)
的语法糖。因此,使用 JSX 可以完成的任何事情都可以通过纯 JavaScript 完成。
例如,用 JSX 编写的代码:
class Hello extends React.Component {
render() {
return <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World" />,
document.getElementById('root')
);
复制代码
可以编写为不使用 JSX 的代码:
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
5.为什么使用jsx的组件中没有看到使用react却需要引入react?
本质上来说JSX是React.createElement(component, props, ...children)
方法的语法糖。在React 17之前,如果使用了JSX,其实就是在使用React, babel
会把组件转换为 CreateElement
形式。在React 17之后,就不再需要引入,因为 babel
已经可以帮我们自动引入react。
async/await是ES7标准中的新特性。如果是使用React官方的脚手架创建的项目,就可以直接使用。如果是在自己搭建的webpack配置的项目中使用,可能会遇到 regeneratorRuntime is not defined 的异常错误。那么我们就需要引入babel,并在babel中配置使用async/await。可以利用babel的 transform-async-to-module-method 插件来转换其成为浏览器支持的语法,虽然没有性能的提升,但对于代码编写体验要更好。
JavaScript中的map不会对为null或者undefined的数据进行处理,而React.Children.map中的map可以处理React.Children为null或者undefined的情况。
使用了装饰模式,高阶组件的运用:
function withWindowWidth(BaseComponent) {
class DerivedClass extends React.Component {
state = {
windowWidth: window.innerWidth,
}
onResize = () => {
this.setState({
windowWidth: window.innerWidth,
})
}
componentDidMount() {
window.addEventListener('resize', this.onResize)
}
componentWillUnmount() {
window.removeEventListener('resize', this.onResize);
}
render() {
return <BaseComponent {...this.props} {...this.state}/>
}
}
return DerivedClass;
}
const MyComponent = (props) => {
return <div>Window width is: {props.windowWidth}</div>
};
export default withWindowWidth(MyComponent);
复制代码
装饰模式的特点是不需要改变 被装饰对象 本身,而只是在外面套一个外壳接口。JavaScript 目前已经有了原生装饰器的提案,其用法如下:
@testable
class MyTestableClass {
}
解答
在 React 16.8版本(引入钩子)之前,使用基于类的组件来创建需要维护内部状态或利用生命周期方法的组件(即componentDidMount
和shouldComponentUpdate
)。基于类的组件是 ES6 类,它扩展了 React 的 Component 类,并且至少实现了render()
方法。
类组件:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
复制代码
函数组件是无状态的(同样,小于 React 16.8版本),并返回要呈现的输出。它们渲染 UI 的首选只依赖于属性,因为它们比基于类的组件更简单、更具性能。
函数组件:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
复制代码
注意:在 React 16.8版本中引入钩子意味着这些区别不再适用(请参阅14和15题)。
进一步阅读
Keys 是 React 用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
在 React 中渲染集合时,向每个重复的元素添加关键字对于帮助React跟踪元素与数据之间的关联非常重要。key 应该是唯一ID,最好是 UUID 或收集项中的其他唯一字符串:
<ul>
{todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
)};
</ul>
复制代码
在集合中添加和删除项目时,不使用键或将索引用作键会导致奇怪的行为。
进一步阅读
解答
如果您尝试直接改变组件的状态,React 将无法得知它需要重新渲染组件。通过使用setState()
方法,React 可以更新组件的UI。
另外,您还可以谈谈如何不保证状态更新是同步的。如果需要基于另一个状态(或属性)更新组件的状态,请向setState()
传递一个函数,该函数将 state 和 props 作为其两个参数:
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
复制代码
进一步阅读