State Management (Context API & Redux)
Tujuan Pembelajaran
- Memahami global state dengan Context API
- Setup Redux Toolkit untuk state management
- Membuat Todo App dengan Redux
A. Context API (Solusi Sederhana)
Buat Context untuk Theme
jsx
// context/ThemeContext.js
import { createContext, useContext, useState } from 'react';
const ThemeContext = createContext();
export function ThemeProvider({ children }) {
const [isDark, setIsDark] = useState(false);
const toggle = () => setIsDark(!isDark);
const theme = {
isDark,
toggle,
colors: isDark
? { bg: '#1a1a1a', text: '#fff', card: '#2d2d2d' }
: { bg: '#f5f5f5', text: '#000', card: '#fff' },
};
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
);
}
export const useTheme = () => useContext(ThemeContext);
Gunakan di Component
jsx
// App.js
import { ThemeProvider, useTheme } from './context/ThemeContext';
import { View, Text, Switch, StyleSheet } from 'react-native';
function HomeScreen() {
const { isDark, toggle, colors } = useTheme();
return (
<View style={[styles.container, { backgroundColor: colors.bg }]}>
<Text style={{ color: colors.text, fontSize: 24 }}>
Mode: {isDark ? 'Gelap' : 'Terang'}
</Text>
<Switch value={isDark} onValueChange={toggle} />
</View>
);
}
export default function App() {
return (
<ThemeProvider>
<HomeScreen />
</ThemeProvider>
);
}
B. Redux Toolkit (Aplikasi Kompleks)
Install Redux
bash
npm install @reduxjs/toolkit react-redux
Buat Slice (store/todoSlice.js)
jsx
import { createSlice } from '@reduxjs/toolkit';
const todoSlice = createSlice({
name: 'todos',
initialState: { items: [] },
reducers: {
addTodo: (state, action) => {
state.items.push({
id: Date.now().toString(),
text: action.payload,
done: false,
});
},
toggleTodo: (state, action) => {
const item = state.items.find(t => t.id === action.payload);
if (item) item.done = !item.done;
},
deleteTodo: (state, action) => {
state.items = state.items.filter(t => t.id !== action.payload);
},
},
});
export const { addTodo, toggleTodo, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
Setup Store (store/index.js)
jsx
import { configureStore } from '@reduxjs/toolkit';
import todoReducer from './todoSlice';
export const store = configureStore({
reducer: { todos: todoReducer },
});
Gunakan di App
jsx
import { Provider, useSelector, useDispatch } from 'react-redux';
import { store } from './store';
import { addTodo, toggleTodo, deleteTodo } from './store/todoSlice';
function TodoApp() {
const todos = useSelector(state => state.todos.items);
const dispatch = useDispatch();
const [text, setText] = useState('');
return (
<View style={{ flex: 1, padding: 20, paddingTop: 50 }}>
<TextInput value={text} onChangeText={setText}
placeholder="Tambah todo..." style={styles.input} />
<Button title="Tambah"
onPress={() => { dispatch(addTodo(text)); setText(''); }} />
<FlatList data={todos} keyExtractor={i => i.id}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => dispatch(toggleTodo(item.id))}
onLongPress={() => dispatch(deleteTodo(item.id))}>
<Text style={{ textDecorationLine: item.done ? 'line-through' : 'none' }}>
{item.text}
</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
export default function App() {
return <Provider store={store}><TodoApp /></Provider>;
}
C. Context vs Redux
- Context API: Cocok untuk state sederhana (theme, auth, language)
- Redux: Cocok untuk state kompleks (shopping cart, data besar)
D. Latihan Mandiri
- Implementasikan Theme toggle (dark/light) dengan Context API
- Buat Todo App dengan Redux Toolkit (add, toggle, delete)
- Gabungkan keduanya dalam satu aplikasi
- Screenshot dan kumpulkan source code