界面上的控件会根据用户的输入而更新。例如,点击按钮切换轮播图的展示。在 React 中,随时间变化的数据被称为状态(state)。你可以向任何组件添加状态,并按需进行更新。
响应事件
React 允许你向 JSX 中添加事件处理程序。事件处理程序是你自己的函数,它将在用户交互时被触发,如点击、悬停、焦点在表单输入框上等等。
<button>
等内置组件只支持内置浏览器事件,如 onClick
。但是,你也可以创建你自己的组件,并给它们的事件处理程序 props 指定你喜欢的任何特定于应用的名称。
export default function App() {
return (
<Toolbar
onPlayMovie={() => alert('Playing!')}
onUploadImage={() => alert('Uploading!')}
/>
);
}
State: 组件的记忆
组件通常需要根据交互改变屏幕上的内容。在表单中键入更新输入栏,在轮播图上点击“下一个”改变显示的图片,点击“购买”将产品放入购物车。组件需要“记住”一些东西:当前的输入值、当前的图片、购物车。在 React 中,这种特定于组件的记忆被称为状态。
你可以用 useState
Hook 为组件添加状态。Hook 是能让你的组件使用 React 功能的特殊函数(状态是这些功能之一)。useState
Hook 让你声明一个状态变量。它接收初始状态并返回一对值:当前状态,以及一个让你更新状态的设置函数。
const [index, setIndex] = useState(0);
渲染和提交
在你的组件显示在屏幕上之前,它们必须由 React 进行渲染。
- 触发渲染(将食客的订单送到厨房)
- 渲染组件(在厨房准备订单)
- 提交到 DOM(将订单送到桌前)
作为快照的状态
与普通 JavaScript 变量不同,React 状态的行为更像一个快照。设置它并不改变你已有的状态变量,而是触发一次重新渲染。
把一系列 state 更新加入队列
设置状态会请求一个新的重新渲染,但不会在已运行的代码中更改它。你可以通过在设置状态时传递一个 更新器函数 来解决这个问题。
const [score, setScore] = useState(0);
function increment() {
setScore(s => s + 1);
}
更新状态中的对象
状态可以持有任何类型的 JavaScript 值,包括对象。但你不应该直接改变你在 React 状态中持有的对象和数组。相反,当你想更新一个对象和数组时,你需要创建一个新的对象(或复制现有的对象),然后用这个副本来更新状态。
通常情况下,你会使用 ...
展开语法来复制你想改变的对象和数组。
setPerson({
...person,
name: e.target.value
});
更新状态中的数组
数组是另一种可以存在状态中的可变 JavaScript 对象,应将其视为只读。就像对象一样,当你想更新存在状态中的数组时,你需要创建一个新数组(或者复制现有数组),然后用新数组来更新状态。
setList(list.map(artwork => {
if (artwork.id === artworkId) {
return { ...artwork, seen: nextSeen };
} else {
return artwork;
}
}));