首頁 > web前端 > js教程 > React Native中的國家管理

React Native中的國家管理

尊渡假赌尊渡假赌尊渡假赌
發布: 2025-02-14 10:23:12
原創
642 人瀏覽過

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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板