这是我参与更文挑战的第15天,活动详情查看:更文挑战
大家好,我是 @洛竹,一个坚持写作的博主,感恩你的每一个点赞和评论。
本文首发于 洛竹的官方网站
本文翻译自 sudheerj/reactjs-interview-questions
本文同步于公众号洛竹早茶馆,转载请联系作者。
1. 什么是切换组件?
切换组件是一个渲染许多组件中的一个组件。我们需要使用对象来将 props 值映射到组件。
例如,一个切换组件可以根据 page props 显示不同的页面。
import HomePage from './HomePage';
import AboutPage from './AboutPage';
import ServicesPage from './ServicesPage';
import ContactPage from './ContactPage';
const PAGES = {
home: HomePage,
about: AboutPage,
services: ServicesPage,
contact: ContactPage,
};
const Page = props => {
const Handler = PAGES[props.page] || ContactPage;
return <Handler {...props} />;
};
// PAGES 对象的键可以在 props 类型中使用,以捕捉开发时间错误。
Page.propTypes = {
page: PropTypes.oneOf(Object.keys(PAGES)).isRequired,
};
复制代码
2. 为什么我们需要向 setState() 传递一个函数?
这背后的原因是,setState() 是一个异步操作。出于性能的考虑,React 会对状态变化进行批处理,所以在调用 setState() 后,状态可能不会立即发生变化。这意味着你在调用 setState() 时不应该依赖当前的状态,因为你不能确定这个状态会是什么。解决办法是将一个函数传递给 setState(),并将之前的状态作为参数。通过这样做,你可以避免由于 setState() 的异步性而导致用户在访问时获得旧的状态值的问题。
假设初始计数值为 0。在连续三次递增操作后,该值将只递增一个。
// 假设 this.state.count === 0
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
this.setState({ count: this.state.count + 1 });
// this.state.count === 1,而不是 3
复制代码
如果我们给 setState() 传递一个函数,计数就会被正确地递增。
this.setState((prevState, props) => ({
count: prevState.count + props.increment,
}));
// this.state.count === 3
复制代码
3. 为什么在 setState() 中首选函数而不是对象?
React 可以将多个 setState() 的调用批量化为一次更新,以提高性能。因为 this.props 和 this.state 可能被异步更新,你不应该依赖它们的值来计算下一个状态。
这个计数器的例子将无法按预期更新。
// 错误❌
this.setState({
counter: this.state.counter + this.props.increment,
});
复制代码
首选的方法是用函数而不是对象调用 setState()。该函数将接收先前的状态作为第一个参数,并将应用更新时的 props 作为第二个参数。
// 正确✅
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment,
}));
复制代码
4. React 中的严格模式是什么?
React.StrictMode 是一个有用的组件,用于暴露应用程序中的潜在问题。就像 <Fragment>,<StrictMode>不会渲染任何额外的 DOM 元素。它为其后代激活了额外的检查和警告。这些检查只适用于开发模式。
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
复制代码
在上面的例子中,严格模式检查只适用于 <ComponentOne> 和 <ComponentTwo> 组件。
5. 为什么 isMounted() 是一个反模式,正确的解决方案是什么?
isMounted() 的主要用例是避免在组件被卸载后调用 setState(),因为它会发出警告。
if (this.isMounted()) {
this.setState({...})
}
复制代码
在调用 setState() 之前检查 isMounted() 确实可以消除警告,但这也违背了警告的目的。使用 isMounted() 是一种代码异味,因为你检查的唯一原因是你认为你可能在组件卸载后还持有一个引用。
一个最佳的解决方案是找到在组件卸载后可能调用 setState() 的地方,并修复它们。这种情况通常是由于回调引起的,当一个组件在等待一些数据时,在数据到达之前被卸载。理想情况下,任何回调都应该在 componentWillUnmount() 中取消(在解除挂载之前)。
代码异味 (Code smell):程序开发领域,代码中的任何可能导致深层次问题的症状都可以叫做代码异味。 通常,在对代码做简短的反馈迭代时,代码异味会暴露出一些深层次的问题,这里的反馈迭代,是指以一种小范围的、可控的方式重构代码。
6. React 中支持哪些指针事件?
指针事件提供了一个处理所有输入事件的统一方法。在过去,我们有一个鼠标和各自的事件监听器来处理它们,但现在我们有许多设备与拥有鼠标不相关,如带有触摸表面的手机或笔。我们需要记住,这些事件只能在支持 Pointer Events 规范的浏览器中工作。
以下事件类型现在在 React DOM 中可用。
onPointerDownonPointerMoveonPointerUponPointerCancelonGotPointerCaptureonLostPointerCaptureonPointerEnteronPointerLeaveonPointerOveronPointerOut
7. 为什么组件名称要以大写字母开头?
如果你使用 JSX 渲染你的组件,该组件的名称必须以大写字母开头,否则 React 将抛出一个错误,即未识别的标签。这个惯例是因为只有 HTML 元素和 SVG 标签可以以小写字母开头。
class SomeComponent extends Component {
// 掘金不止,代码不停
}
复制代码
你可以定义名称以小写字母开头的组件类,但当它被导入时,它应该是大写字母。在这里,小写就可以了。
class myComponent extends Component {
render() {
return <div />;
}
}
export default myComponent;
复制代码
而当导入另一个文件时,它应该以大写字母开始。
import MyComponent from './MyComponent';
复制代码
关于 React 组件的命名,有哪些例外情况?
组件名称应以大写字母开头,但这一惯例也有少数例外。带点的小写标签名(属性访问器)仍被认为是有效的组件名。
例如,下面的标签可以被编译成一个有效的组件。
render(){
return (
<obj.component /> // `React.createElement(obj.component)`
)
}
复制代码
8. React v16 中支持自定义 DOM 属性吗?
是的,在过去,React 习惯于忽略未知的 DOM 属性。如果你写的 JSX 有一个 React 不认识的属性,React 会直接跳过它。
例如,让我们看一下下面的属性。
<div mycustomattribute={'something'} />
复制代码
用 React v15 渲染一个空的 div 到 DOM 上。
<div />
复制代码
在 React v16 中,任何未知的属性最终都会出现在 DOM 中。
<div mycustomattribute="something" />
复制代码
这对于提供浏览器特定的非标准属性,尝试新的 DOM API,以及与有主见的第三方库集成是非常有用的。
9. constructor 和 getInitialState 的区别是什么?
当使用 ES6 类时,你应该在构造函数中初始化状态,而当使用 React.createClass() 时,应该在 getInitialState() 方法中初始化状态。
使用 ES6 类:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
/* 初始化状态 */
};
}
}
复制代码
使用 React.createClass():
const MyComponent = React.createClass({
getInitialState() {
return {
/* 初始化状态 */
};
},
});
复制代码
注意: React.createClass() 在 React v16 中已被废弃并删除。请使用普通的 JavaScript 类来代替。
10. 你能在不调用 setState 的情况下强制一个组件重新渲染吗?
默认情况下,当你的组件的状态或 props 改变时,你的组件会重新渲染。如果你的 render() 方法依赖于其他数据,你可以通过调用 forceUpdate() 告诉 React 该组件需要重新渲染。
component.forceUpdate(callback);
复制代码
建议避免使用 forceUpdate(),只在 render() 中读取this.props 和 this.state。






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)