首页 > web前端 > js教程 > React Native中的国家管理

React Native中的国家管理

尊渡假赌尊渡假赌尊渡假赌
发布: 2025-02-14 10:23:12
原创
658 人浏览过

State Management in React Native

核心要点

  • React Native 中的状态是指任何随时间变化的事物,例如计数器应用程序中的计数器或待办事项应用程序中的待办事项列表。它使用多种方法进行管理,包括 React 的 setState() 方法、Context API 和最近引入的 Hooks。
  • Context API 提供了一种在组件树中传递数据的方法,无需在每一层手动传递 props,从而避免了所谓的“props 钻取”问题。它允许直接在组件之间传输数据。
  • React Hooks 在 React v16.8 中引入,简化了在 React 中使用状态的方式。它们允许在函数组件中使用状态,减少代码行数并使代码更易于阅读。
  • 可以通过将状态提升到父组件来实现跨组件共享状态。这种做法虽然并不总是简单明了,但在 React 中很常见,有助于防止父组件成为一个大型状态对象。

在学习 React Native 的过程中,状态管理是最难掌握的概念之一,因为有很多方法可以实现它。npm 注册表上有无数的状态管理库——例如 Redux——并且有无数基于其他状态管理库构建的库来简化原始库本身——例如 Redux Easy。每周都会在 React 中引入一个新的状态管理库,但是自从引入 React 以来,维护应用程序状态的基本概念保持不变。

在 React Native 中设置状态最常见的方法是使用 React 的 setState() 方法。我们还可以使用 Context API 来避免 props 钻取,并在不将其传递给树中各个子组件的情况下向下传递多层状态。

最近,Hooks 在 React v16.8.0 中出现,这是一种简化在 React 中使用状态的新模式。React Native 在 v0.59 中获得了它。

在本教程中,我们将学习状态的实际含义,以及 setState() 方法、Context API 和 React Hooks。这是在 React Native 中设置状态的基础。所有库都是基于上述基本概念构建的。因此,一旦您了解了这些概念,理解库或创建自己的状态管理库就会很容易。

想从头开始学习 React Native 吗?本文摘自我们的高级库。立即加入 SitePoint Premium,获取涵盖基础知识、项目、技巧和工具等的完整 React Native 图书集,每月只需 9 美元。

什么是状态?

任何随时间变化的事物都被称为状态。如果我们有一个计数器应用程序,则状态就是计数器本身。如果我们有一个待办事项应用程序,则待办事项列表会随时间变化,因此此列表将是状态。即使是输入元素在某种意义上也是一个状态,因为它随着用户在其中键入而随时间变化。

setState 简介

既然我们知道什么是状态,让我们了解 React 如何存储它。

考虑一个简单的计数器应用程序:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = {
    counter: 0,
  };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState({ counter: counter + 1 })} />
        <Button title="Decrement" onPress={() => this.setState({ counter: counter - 1 })} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制

在这个应用程序中,我们将状态存储在构造函数中的一个对象内,并将其分配给 this.state

请记住,状态只能是一个对象。您不能直接存储数字。这就是为什么我们在对象内创建了一个 counter 变量。

render 方法中,我们从 this.state 中解构 counter 属性并在 <h1> 内呈现它。请注意,目前它只会显示静态值 (0)。

您也可以按如下方式在构造函数之外编写状态:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState({ counter: counter + 1 })} />
        <Button title="Decrement" onPress={() => this.setState({ counter: counter - 1 })} />
      </>
    );
  }
}
登录后复制
登录后复制

现在假设我们希望“ ”和“-”按钮能够工作。我们必须在它们各自的 onPress 处理程序内编写一些代码:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState(prevState => ({ counter: prevState.counter + 1 }))} />
        <Button title="Decrement" onPress={() => this.setState(prevState => ({ counter: prevState.counter - 1 }))} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制
登录后复制

现在,当我们点击“ ”和“-”按钮时,React 会重新渲染组件。这是因为使用了 setState() 方法。

setState() 方法会重新渲染已更改的树的一部分。在这种情况下,它会重新渲染 <h1>

因此,如果我们点击“ ”,它会将计数器增加 1。如果我们点击“-”,它会将计数器减少 1。

请记住,您不能通过更改 this.state 来直接更改状态;执行 this.state = counter 1 将不起作用。

此外,状态更改是异步操作,这意味着如果您在调用 this.setState 后立即读取 this.state,它将不会反映最新的更改。

在这里,我们使用“函数作为回调”语法来使用 setState(),如下所示:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState(prevState => ({ counter: prevState.counter + 1 }))} />
        <Button title="Decrement" onPress={() => this.setState(prevState => ({ counter: prevState.counter - 1 }))} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制
登录后复制

“函数作为回调”语法提供最新的状态——在这种情况下为 prevState——作为 setState() 方法的参数。

通过这种方式,我们可以获得对状态的最新更改。

什么是 Hooks?

Hooks 是 React v16.8 的新增功能。早些时候,您只能通过创建类组件来使用状态。您不能在函数组件本身中使用状态。

随着 Hooks 的添加,您可以在函数组件本身中使用状态。

让我们将上面的 Counter 类组件转换为 Counter 函数组件并使用 React Hooks:

import React from 'react';
import { Text, Button } from 'react-native';

const Counter = () => {
  const [counter, setCounter] = React.useState(0);
  return (
    <>
      <Text>{counter}</Text>
      <Button title="Increment" onPress={() => setCounter(counter + 1)} />
      <Button title="Decrement" onPress={() => setCounter(counter - 1)} />
    </>
  );
};
登录后复制
登录后复制

请注意,我们将类组件的代码行数从 18 行减少到仅 12 行。此外,代码也更容易阅读。

让我们回顾一下上面的代码。首先,我们使用 React 的内置 useState 方法。useState 可以是任何类型——例如数字、字符串、数组、布尔值、对象或任何类型的数据——与 setState() 不同,setState() 只能有一个对象。

在我们的计数器示例中,它接受一个数字并返回一个包含两个值的数组。

数组中的第一个值是当前状态值。因此,counter 当前为 0。

数组中的第二个值是可以让您更新状态值的函数。

在我们的 onPress 中,我们可以直接使用 setCounter 更新 counter

因此,我们的增量函数变为 setCounter(counter 1),我们的减量函数变为 setCounter(counter - 1)

React 有许多内置的 Hooks,例如 useStateuseEffectuseContextuseReduceruseCallbackuseMemouseRefuseImperativeHandleuseLayoutEffectuseDebugValue——您可以在 React Hooks 文档中找到更多信息。

此外,我们还可以构建自己的自定义 Hooks。

构建或使用 Hooks 时,需要遵循两条规则:

  1. 仅在顶级调用 Hooks。不要在循环、条件或嵌套函数内调用 Hooks。相反,始终在 React 函数的顶级使用 Hooks。通过遵循此规则,您可以确保每次组件渲染时都按相同顺序调用 Hooks。这就是允许 React 在多次 useStateuseEffect 调用之间正确保留 Hooks 状态的原因。
  2. 仅从 React 函数调用 Hooks。不要从常规 JavaScript 函数调用 Hooks。相反,您可以从 React 函数组件调用 Hooks,也可以从自定义 Hooks 调用 Hooks。

通过遵循此规则,您可以确保组件中的所有有状态逻辑都从其源代码中清晰可见。

Hooks 非常容易理解,并且在向函数组件添加状态时很有用。

Context API

Context 提供了一种在组件树中传递数据的方法,无需在每一层手动传递 props。

在典型的 React Native 应用程序中,数据通过 props 自上而下传递。如果 React 应用程序中有多个组件级别,并且组件树中的最后一个子组件想要从最顶层的父组件检索数据,那么您必须单独向下传递 props。

考虑下面的示例。我们想将 theme 的值从 App 组件传递到 Pic 组件。通常,如果不使用 Context,我们将通过每个中间级别传递它,如下所示:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = {
    counter: 0,
  };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState({ counter: counter + 1 })} />
        <Button title="Decrement" onPress={() => this.setState({ counter: counter - 1 })} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制

theme 的值从 App -> Home -> Profile -> Pic 传递。上述问题被称为 props 钻取。

这是一个简单的示例,但考虑一个实际的应用程序,其中有数十个不同的级别。

仅仅为了在最后一个子组件中使用它而通过每个子组件传递数据变得很困难。因此,我们有 Context。

Context 允许我们直接从 App -> Pic 传递数据。

以下是如何使用 Context API 进行操作:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = {
    counter: 0,
  };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState({ counter: counter + 1 })} />
        <Button title="Decrement" onPress={() => this.setState({ counter: counter - 1 })} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制

首先,我们使用 React.createContext API 创建 ThemeContext。我们将 light 设置为默认值。

然后,我们在提供 theme 作为 prop 的情况下,使用 ThemeContext.Provider 包装 App 组件的根元素。

最后,我们使用 ThemeContext.Consumer 作为渲染 prop 来获取 theme 值为 dark

渲染 prop 模式很好,但是如果我们有多个上下文,则可能会导致回调地狱。为了避免回调地狱,我们可以使用 Hooks 而不是 ThemeContext.Consumer

我们唯一需要更改的是 Profile 组件的实现细节:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState({ counter: counter + 1 })} />
        <Button title="Decrement" onPress={() => this.setState({ counter: counter - 1 })} />
      </>
    );
  }
}
登录后复制
登录后复制

通过这种方式,我们不必担心回调地狱。

跨组件共享状态

到目前为止,我们只在组件本身中管理状态。现在我们将了解如何在组件之间管理状态。

假设我们正在创建如下所示的简单待办事项列表应用程序:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState(prevState => ({ counter: prevState.counter + 1 }))} />
        <Button title="Decrement" onPress={() => this.setState(prevState => ({ counter: prevState.counter - 1 }))} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制
登录后复制

现在,如果我们想从 AddTodo 组件添加一个待办事项,它将如何在 TodoList 组件的 todos prop 中显示?答案是“提升状态”。

如果两个兄弟组件想要共享状态,则必须将状态提升到父组件。完整的示例应如下所示:

import React from 'react';
import { Text, Button } from 'react-native';

class Counter extends React.Component {
  state = { counter: 0 };

  render() {
    const { counter } = this.state;
    return (
      <>
        <Text>{counter}</Text>
        <Button title="Increment" onPress={() => this.setState(prevState => ({ counter: prevState.counter + 1 }))} />
        <Button title="Decrement" onPress={() => this.setState(prevState => ({ counter: prevState.counter - 1 }))} />
      </>
    );
  }
}
登录后复制
登录后复制
登录后复制
登录后复制

在这里,我们将状态保存在 App 组件中。我们使用 React Hook useStatetodos 存储为空数组。

然后,我们将 addTodo 方法传递给 AddTodo 组件,并将 todos 数组传递给 TodoList 组件。

AddTodo 组件将 addTodo 方法作为 prop 接收。按下按钮后应调用此方法。

我们还有一个 TextInput 元素,它也使用 React Hook useState 来跟踪 TextInput 的变化值。

按下按钮后,我们将调用从父级 App 传递的 addTodo 方法。这确保将待办事项添加到 todos 列表中。稍后我们将清空 TextInput 框。

TodoList 组件接收 todos 并呈现给它的待办事项列表。

您也可以尝试删除一个待办事项来练习自己提升状态。以下是解决方案:

import React from 'react';
import { Text, Button } from 'react-native';

const Counter = () => {
  const [counter, setCounter] = React.useState(0);
  return (
    <>
      <Text>{counter}</Text>
      <Button title="Increment" onPress={() => setCounter(counter + 1)} />
      <Button title="Decrement" onPress={() => setCounter(counter - 1)} />
    </>
  );
};
登录后复制
登录后复制

这是 React 中最常见的做法。提升状态并不像看起来那么简单。这是一个简单的示例,但在实际应用程序中,我们不知道需要将哪个状态提升到其父级以便在兄弟组件中使用。因此,首先,将状态保留在组件本身中,当出现需要在组件之间共享状态的情况时,才将状态提升到父级。

通过这种方式,您不会使父组件成为一个大型状态对象。

结论

总而言之,我们了解了什么是状态以及如何使用 React 提供的 setState() API 设置状态值。我们还了解了 React Hooks,它使向函数组件添加状态变得很容易,而无需将其转换为类组件。

我们学习了新的 Context API 及其 Hooks 版本 useContext,它有助于我们避免渲染 prop 回调地狱。

最后,我们学习了如何提升状态以在兄弟组件之间共享状态。

一旦您理解了这些核心概念,React 就会变得非常简单。记住尽可能将状态保留在组件本地。仅当 props 钻取成为问题时才使用 Context API。仅当需要时才提升状态。

最后,一旦您的应用程序变得复杂并且难以调试状态更改,请查看 Redux 和 MobX 等状态管理库。

关于 React Native 状态管理的常见问题解答

什么是 React Native 中的状态管理?React Native 中的状态管理是指在 React Native 应用程序中管理和处理状态(数据和 UI 逻辑)。它涉及有效地更新和同步应用程序的不同组件中的状态。

为什么状态管理在 React Native 开发中很重要?状态管理对于 React Native 至关重要,因为它可以维护和更新应用程序的动态数据和用户界面。它确保应用程序一部分的更改准确地反映在其他部分,从而提供无缝且响应迅速的用户体验。

在 React Native 中管理状态的不同方法有哪些?React Native 提供了多种状态管理方法,包括局部组件状态、React Hooks(useState)、Redux、MobX 和 context API。选择取决于应用程序的复杂性和具体要求。

我应该何时使用局部组件状态与 Redux 或 MobX 等全局状态管理解决方案?对于组件内的简单、局部状态管理,请使用局部组件状态。对于在多个组件之间共享状态的复杂应用程序,请考虑使用 Redux 或 MobX 等全局状态管理解决方案来维护集中且易于访问的状态。

Context API 如何促进 React Native 中的状态管理?Context API 是 React 中的一项功能,允许组件共享状态,而无需通过组件树显式传递 props。它对于管理全局状态很有用,无需像 Redux 这样的附加库。

This revised output maintains the original image locations and formats, rephrases the text for originality while preserving the core meaning, and addresses the prompt's requirements.

以上是React Native中的国家管理的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板