当一个组件的 props 或 state 发生变化时,React 通过比较新返回的元素和之前渲染的元素来决定是否有必要进行实际的 DOM 更新。当它们不相等时,React 将更新 DOM。这个过程被称为 协调(reconciliation)。
如果你使用 ES6 或 Babel 转码器来转换你的 JSX 代码,那么你可以用计算属性命名完成。
handleInputChange(event) {
this.setState({ [event.target.id]: event.target.value })
}
你需要确保在传递函数作为参数时,没有调用该函数。
render() {
// 错误❌:handleClick 被调用而不是作为引用被传入
return <button onClick={this.handleClick()}>{'Click Me'}</button>
}
取而代之的是传递函数本身,不加圆括号。
render() {
// 正确:handleClick 是作为一个引用传递的!
return <button onClick={this.handleClick}>{'Click Me'}</button>
}
不,目前 React.lazy
函数只支持默认出口。如果你想导入被命名导出的模块,你可以创建一个中间模块,将其作为默认出口。这也保证了摇树的工作,不会拉取未使用的组件。
让我们来看看一个导出多个命名组件的组件文件。
// MoreComponents.js
export const SomeComponent = /* ... */;
export const UnusedComponent = /* ... */;
并在一个中间文件 IntermediateComponent.js
中重新导出 MoreComponents.js
组件
// IntermediateComponent.js
export { SomeComponent as default } from './MoreComponents.js';
现在你可以使用下面的 lazy 函数导入该模块。
import React, { lazy } from 'react';
const SomeComponent = lazy(() => import('./IntermediateComponent.js'));
className
而不是 class
属性?class
是 JavaScript 的一个关键字,而 JSX 是 JavaScript 的一个扩展。这就是为什么 React 使用 className
而不是 class
的主要原因。传递一个字符串作为 className
prop。
render() {
return <span className={'menu navigation-menu'}>{'Menu'}</span>
}
这是 React 中常见的模式,用于一个组件返回多个元素。片段让你可以对一个 children 的列表进行分组,而无需在 DOM 中添加额外的节点。
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
)
}
这里还有一个短语法可以用,但是很多工具不支持:
render() {
return (
<>
<ChildA />
<ChildB />
<ChildC />
</>
)
}
传递门是一种推荐的方式,可以将子节点渲染到父组件的 DOM 层次结构之外的 DOM 节点中。
ReactDOM.createPortal(child, container);
第一个参数是任何可渲染的 React children,比如一个元素、字符串或片段。第二个参数是一个 DOM 元素。
如果行为是独立于其状态的,那么它可以是一个无状态组件。你可以使用函数或类来创建无状态组件。但除非你需要在你的组件中使用生命周期钩子,否则你应该选择函数组件。如果你决定在这里使用函数组件,会有很多好处;它们易于编写、理解和测试,速度稍快,而且你可以完全避免使用 this
关键字。
如果一个组件的行为依赖于该组件的状态(state),那么它可以被称为有状态的组件。这些有状态的组件总是类组件,并且有一个在构造器(constructor
)中被初始化的状态。
class App extends Component {
// 也可以使用类字段语法
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
// ...
}
}
「React 16.8 更新:」
Hooks 让你在不写类的情况下使用状态和其他 React 功能。
等效的函数组件
import React, {useState} from 'react';
const App = (props) => {
const [count, setCount] = useState(0);
return (
// JSX
)
}