React Managing State

React Managing State

The library for web and native user interfaces
随着你的应用不断变大,更有意识的去关注应用状态如何组织,以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。

使用状态响应输入

使用 React,你不用直接从代码层面修改 UI。例如,不用编写诸如“禁用按钮”、“启用按钮”、“显示成功消息”等命令。相反,你只需要描述组件在不同状态(“初始状态”、“输入状态”、“成功状态”)下希望展现的 UI,然后根据用户输入触发状态更改。这和设计师对 UI 的理解很相似。

选择状态结构

良好的状态组织,可以区分开易于修改和调试的组件与频繁出问题的组件。最重要的原则是,状态不应包含冗余或重复的信息。如果包含一些多余的状态,我们会很容易忘记去更新它,从而导致问题产生!

在组件间共享状态

有时候你希望两个组件的状态始终同步更改。要实现这一点,可以将相关状态从这两个组件上移除,并把这些状态移到最近的父级组件,然后通过 props 将状态传递给这两个组件。这被称为“状态提升”。

保留和重置状态

当你重新渲染一个组件时, React 需要决定组件树中的哪些部分要保留和更新,以及丢弃或重新创建。在大多数情况下, React 的自动处理机制已经做得足够好了。默认情况下,React 会保留树中与先前渲染的组件树“匹配”的部分。

React 允许你覆盖默认行为,可通过向组件传递一个唯一 key(如 <Chat key={email}/>强制 重置其状态。这会告诉 React ,如果收件人不同,应将其作为一个 不同的 Chat 组件,需要使用新数据和 UI(比如输入框)来重新创建它。现在,在接收者之间切换时就会重置输入框——即使渲染的是同一个组件。

<Chat key={to.email} contact={to} />

提取状态逻辑到 reducer 中

对于那些需要更新多个状态的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以在组件外部将所有状态更新逻辑合并到一个称为 “reducer” 的函数中。这样,事件处理程序就会变得简洁,因为它们只需要指定用户的 “actions”。在文件的底部,reducer 函数指定状态应该如何更新以响应每个 action!

  const [tasks, dispatch] = useReducer(
    tasksReducer,
    initialTasks
  );
  dispatch({
    type: 'added',
    id: nextId++,
    text: text,
  });
  function tasksReducer(tasks, action) {
  switch (action.type) {
    case 'added': {
    ...

使用 Context 进行深层数据传递

Context 允许父组件将一些信息提供给它下层的任何组件,不管该组件多深层也无需通过 props 逐层透传。

import { createContext } from 'react';

export const ThemeContext = createContext('dark');

ThemeContext.js

import { ThemeContext } from './ThemeContext.js';

export default function App() {
  const [theme, setTheme] = useState("dark");
  return (
    <ThemeContext.Provider value={theme}>
      <Children />
    </ThemeContext.Provider>
  );
}

App.js

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext.js';

export default function Children() {
  const theme = useContext(ThemeContext)
  return (
    <div>{theme}<div />
  );
}

Children.js

使用 Reducer 和 Context 进行状态扩展

Reducer 帮助你合并组件的状态更新逻辑。Context 帮助你将信息深入传递给其他组件。你可以将 reducers 和 context 组合在一起使用,以管理复杂应用的状态。

基于这种想法,使用 reducer 来管理一个具有复杂状态的父组件。组件树中任何深度的其他组件都可以通过 context 读取其状态。还可以 dispatch 一些 action 来更新状态。

Rick Zheng

Rick Zheng

Scientist working on creating NekoMusume
Shanghai