Created
September 25, 2024 12:14
-
-
Save harilee1325/b4cf1ee842d28dfa3aeb05f5c9db0c40 to your computer and use it in GitHub Desktop.
React Native State Management
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1. Local Component State (Using useState) | |
For managing state within a single component, React Native's built-in useState Hook is often sufficient. This is suitable for simple use cases where the state is not shared across multiple components. | |
Example: | |
jsx | |
Copy code | |
import React, { useState } from 'react'; | |
import { View, Text, Button } from 'react-native'; | |
const Counter = () => { | |
const [count, setCount] = useState(0); | |
return ( | |
<View> | |
<Text>Count: {count}</Text> | |
<Button title="Increment" onPress={() => setCount(count + 1)} /> | |
</View> | |
); | |
}; | |
In this example, the useState hook manages the state of count locally within the Counter component. This is ideal when the state is only needed in this component. | |
2. Lifting State Up (Prop Drilling) | |
When multiple components need to share state, you can lift the state up to a common parent component and pass it down as props to child components. This technique is called prop drilling. | |
Example: | |
jsx | |
Copy code | |
const ParentComponent = () => { | |
const [message, setMessage] = useState('Hello World!'); | |
return <ChildComponent message={message} />; | |
}; | |
const ChildComponent = ({ message }) => { | |
return <Text>{message}</Text>; | |
}; | |
While this works for smaller apps, it can get messy in larger apps where state needs to be passed through multiple levels of components. | |
3. Context API (For Global State) | |
The React Context API allows you to manage global state and share data across the entire component tree without passing props manually at every level. This is useful for medium-sized apps where you want to avoid prop drilling. | |
Steps to use Context API: | |
Create a Context: You create a context using React.createContext(). | |
Provide the Context: Use the Context.Provider component to provide state. | |
Consume the Context: Use useContext to access the context in any child component. | |
Example: | |
jsx | |
Copy code | |
import React, { createContext, useContext, useState } from 'react'; | |
const ThemeContext = createContext(); | |
const ParentComponent = () => { | |
const [theme, setTheme] = useState('light'); | |
return ( | |
<ThemeContext.Provider value={theme}> | |
<ChildComponent /> | |
</ThemeContext.Provider> | |
); | |
}; | |
const ChildComponent = () => { | |
const theme = useContext(ThemeContext); // Consuming context | |
return <Text>The current theme is {theme}</Text>; | |
}; | |
In this example, ThemeContext provides a value (theme), which can be accessed in any component inside its tree, without passing props manually. | |
4. Redux (For Complex State Management) | |
For larger applications, you may need a more robust solution for managing complex state across many components. Redux is a popular state management library that works well with React and React Native. | |
Redux provides a centralized store where all the application's state resides. Components can dispatch actions to modify the state, and reducers handle the changes based on those actions. | |
Key Concepts in Redux: | |
Store: The global state container for your app. | |
Action: An object that describes an event (e.g., "ADD_ITEM") and carries a payload. | |
Reducer: A pure function that takes the current state and an action, and returns the next state. | |
Dispatch: A method to send actions to the store. | |
Selectors: Functions to access the state in the store. | |
Example using Redux in React Native: | |
Install Redux and React-Redux: | |
bash | |
Copy code | |
npm install redux react-redux | |
Create a Redux Store: | |
javascript | |
Copy code | |
import { createStore } from 'redux'; | |
const initialState = { count: 0 }; | |
const reducer = (state = initialState, action) => { | |
switch (action.type) { | |
case 'INCREMENT': | |
return { ...state, count: state.count + 1 }; | |
default: | |
return state; | |
} | |
}; | |
const store = createStore(reducer); | |
Connect Redux to React Native: Wrap your app with the Provider component from react-redux and pass it the store. | |
jsx | |
Copy code | |
import { Provider } from 'react-redux'; | |
const App = () => ( | |
<Provider store={store}> | |
<Counter /> | |
</Provider> | |
); | |
Create a Connected Component: Use the useSelector hook to access the state, and the useDispatch hook to dispatch actions. | |
jsx | |
Copy code | |
import { useSelector, useDispatch } from 'react-redux'; | |
const Counter = () => { | |
const count = useSelector((state) => state.count); | |
const dispatch = useDispatch(); | |
return ( | |
<View> | |
<Text>Count: {count}</Text> | |
<Button title="Increment" onPress={() => dispatch({ type: 'INCREMENT' })} /> | |
</View> | |
); | |
}; | |
In this example, Counter accesses the global count from the Redux store and can dispatch the INCREMENT action to update the count. | |
5. Zustand (Simpler Alternative to Redux) | |
If Redux feels too complex for your needs, Zustand is a lightweight state management library that simplifies global state management in React Native apps. It uses hooks and provides a much simpler API than Redux. | |
Example using Zustand: | |
Install Zustand: | |
bash | |
Copy code | |
npm install zustand | |
Create a Zustand Store: | |
javascript | |
Copy code | |
import create from 'zustand'; | |
const useStore = create((set) => ({ | |
count: 0, | |
increment: () => set((state) => ({ count: state.count + 1 })), | |
})); | |
Access Zustand Store in Components: | |
jsx | |
Copy code | |
const Counter = () => { | |
const { count, increment } = useStore(); | |
return ( | |
<View> | |
<Text>Count: {count}</Text> | |
<Button title="Increment" onPress={increment} /> | |
</View> | |
); | |
}; | |
With Zustand, the state is easy to set up and use, without the complexity of Redux reducers and actions. | |
6. MobX (Reactive State Management) | |
MobX is another popular state management library that focuses on reactive programming. With MobX, the state is automatically updated when it changes, thanks to its observable properties. | |
Example using MobX: | |
Install MobX and MobX-React: | |
bash | |
Copy code | |
npm install mobx mobx-react | |
Create an Observable State: | |
javascript | |
Copy code | |
import { makeAutoObservable } from 'mobx'; | |
class CounterStore { | |
count = 0; | |
constructor() { | |
makeAutoObservable(this); | |
} | |
increment() { | |
this.count += 1; | |
} | |
} | |
export const counterStore = new CounterStore(); | |
Use MobX in a Component: Use the observer function to automatically update the UI when the state changes. | |
jsx | |
Copy code | |
import { observer } from 'mobx-react'; | |
import { counterStore } from './CounterStore'; | |
const Counter = observer(() => ( | |
<View> | |
<Text>Count: {counterStore.count}</Text> | |
<Button title="Increment" onPress={() => counterStore.increment()} /> | |
</View> | |
)); | |
MobX simplifies state management by using observable properties that automatically update the UI when the state changes, avoiding the need to explicitly wire up actions, reducers, and dispatches like in Redux. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment