大家好,我是 @洛竹
本文首发于 洛竹的官方网站
本文翻译自 sudheerj/reactjs-interview-questions
本文同步于公众号洛竹早茶馆,转载请联系作者。
1. 为什么我们不能直接更新状态?
如果你尝试直接更新状态,React 组件并不会重新渲染。
// 错误❌
this.state.message = 'Hello world';
正确的做法是使用 setState()
方法。它会计划一个对组件状态对象的更新。当状态更改时,组件通过重新渲染进行响应。
// 正确✅
this.setState({ message: 'Hello World' });
注意:你可以使用构造函数或者最新的 javascript class 字段声明语法直接将其分配给状态对象。
2. 回调函数作为 setState()
的参数的目的是什么?
setState 完成并重新渲染组件后,将调用回调函数。由于 setState() 是异步的,因此回调函数可用于任何后续操作。
注意:我们建议使用生命周期方法而不是这个回调函数
setState({ name: 'John' }, () =>
console.log('The name has updated and component re-rendered'),
);
3. HTML 和 React 的事件处理有什么不同?
下面是一些 HTML 和 React 的事件处理的主要不同:
- 在 HTML 中,事件名应该是全小写的:
<button onclick="activateLasers()"></button>
然而在 React 中事件名遵循小驼峰 格式:
<button onClick={activateLasers}>
- 在 HTML 中,你应该返回
false
来阻止默认行为:
<a href="#" onclick='console.log("The link was clicked."); return false;' />
然后在 React 中你必须明确地调用 preventDefault()
function handleClick(event) {
event.preventDefault();
console.log('The link was clicked.');
}
- 在 HTML 中,你调用函数时需要加上
()
:
然后在 React 中你不应该在函数名后带上 ()
。(比如前面示例中的 activateLasers
函数)
4. 如何在 JSX 回调函数中绑定方法或事件处理器
这里有 3 个方法做到这一点:
- 在构造器中绑定: 在 JavaScript 类中,默认情况下不绑定方法。同样的事情也适用于定义为类方法的 React 事件处理器。通常我们将它们绑定在构造函数中。
class Component extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}
}
- 类的公共字段语法: 如果你不喜欢使用绑定的方式,也可以使用类的公共字段语法来正确绑定回调:
handleClick = () => {
console.log('this is:', this);
};
<button onClick={this.handleClick}>{'Click me'}</button>
- 箭头函数作为回调: 你可以直接在回调中使用箭头函数
<button onClick={event => this.handleClick(event)}>{'Click me'}</button>
注意: 如果回调作为 prop 传递给子组件,这些组件可能会触发额外的重渲染。在这些场景中,考虑到性能因素,最佳的选择是使用
.bind()
或类的公共字段语法。
5. 如何传递参数给事件处理器或回调?
你可以使用一个箭头函数来包裹一个事件处理器并传递参数:
<button onClick={() => this.handleClick(id)} />
这等价于调用 .bind
函数:
<button onClick={this.handleClick.bind(this, id)} />
除了这两种办法,你也可以传递参数给一个箭头函数:
<button onClick={this.handleClick(id)} />;
handleClick = id => () => {
console.log('Hello, your ticket number is', id);
};
6. React 中的合成事件是什么?
SyntheticEvent
是基于浏览器本地事件的跨浏览器包装。它的 API 与浏览器的本地事件相同,包括 stopPropagation()
和 preventDefault()
,但事件在所有浏览器中的表现均一致。
7. 什么是内联条件表达式?
你可以使用 JS 可用的 if
语句或三元表达式来有条件地渲染表达式。 除了这些方法之外,还可以通过将所有表达式括在花括号中然后在其后跟JS逻辑运算符 &&
来将任何表达式嵌入JSX。
<h1>Hello!</h1>;
{
messages.length > 0 && !isLogin ? (
<h2>You have {messages.length} unread messages.</h2>
) : (
<h2>You don't have unread messages.</h2>
);
}
8. 什么是 key
prop?在元素数组中使用它的好处是什么?
key
是当你创建一个元素数组时应该包含的一个特殊的字符串属性。key
prop 会帮助 React 识别具体哪一项被修改、添加或被移除。
通常,我们将数据中的 ID 用作 key
:
const todoItems = todos.map(todo => <li key={todo.id}>{todo.text}</li>);
如果呈现的项目没有稳定的 ID,退而求其次,我们可以将 index
作为 key
:
const todoItems = todos.map((todo, index) => <li key={index.toString()}>{todo.text}</li>);
注意:
- 如果列表项可能改变,不建议使用
indexes
作为keys
。这可能会对性能产生负面影响,并可能导致组件状态出现问题。 - 如果你将列表项提取为单独的组件,则在列表组件上应用
keys
而不是li
标签。 - 如果列表项中不存在
key
prop,则控制台中将出现警告消息。
9. refs 有什么用?
refs 用于返回对该元素的引用。在大多数情况下,应避免使用它们,但是,当你需要直接访问 DOM 元素或组件的实例时,它们会很有用。
10. 如何创建 refs?
这里有两种方式
1.这是最近添加的方法。使用 React.createRef()
方法创建 refs,并通过 ref 属性附加到 React 元素。为了在整个组件中使用 refs,只需将ref 分配给构造函数中的 instance 属性。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
- 无论 React 版本如何,你都可以使用 ref 回调方法。例如,搜索栏组件的输入元素的访问方式如下。
class SearchBar extends Component {
constructor(props) {
super(props);
this.txtSearch = null;
this.state = { term: '' };
this.setInputSearchRef = e => {
this.txtSearch = e;
};
}
onInputChange(event) {
this.setState({ term: this.txtSearch.value });
}
render() {
return (
<input
value={this.state.term}
onChange={this.onInputChange.bind(this)}
ref={this.setInputSearchRef}
/>
);
}
}
你也可以使用闭包在函数组件中使用 refs。
注意: 你也可以使用内联 ref 回调,即使这不是推荐的方法
结语
关注公众号洛竹早茶馆
,一个持续分享编程知识的地方。
点赞
等于学会,在看
等于精通- 最后祝大家 2021 学习进步,升职加薪