State Management Evolution

Compare different approaches to state management using counters and API data fetching. See how Redux, Context API, and Zustand handle various use cases.

⚡ Counter State Operations ⚡

Context Counter

0

React Context API for component-level state sharing.

Context Implementation

// counter-context.tsx
const CounterContext = createContext({
  count: 0,
  increment: () => {},
  decrement: () => {},
  reset: () => {}
});

export function CounterProvider({ children }) {
  const [count, setCount] = useState(0);

  const increment = () => setCount(prev => prev + 1);
  const decrement = () => setCount(prev => prev - 1);
  const reset = () => setCount(0);

  return (
    <CounterContext.Provider value={{
      count, increment, decrement, reset
    }}>
      {children}
    </CounterContext.Provider>
  );
}

Redux Counter

0

Redux with Redux Toolkit for predictable state updates.

Redux Implementation

// counter-slice.ts
const counterSlice = createSlice({
  name: 'counter',
  initialState: { count: 0 },
  reducers: {
    increment: (state) => {
      state.count += 1;
    },
    decrement: (state) => {
      state.count -= 1;
    },
    reset: (state) => {
      state.count = 0;
    }
  }
});

export const { increment, decrement, reset } = counterSlice.actions;

Zustand Counter

0

Zustand for simple yet powerful state management.

Zustand Implementation

// counter-store.ts
export const useCounterStore = create((set) => ({
  count: 0,
  increment: () => 
    set((state) => ({ count: state.count + 1 })),
  decrement: () => 
    set((state) => ({ count: state.count - 1 })),
  reset: () => 
    set({ count: 0 })
}));


🌐 Posts State Operations 🌐

Context Posts

Context Implementation


                  const PostsContext = createContext<PostsContextType>({
                    posts: [],
                    loading: false,
                    error: null,
                    fetchPosts: async () => {},
                  });

                  export function PostsProvider({ children }) {
                    const [posts, setPosts] = useState<Post[]>([]);
                    const [loading, setLoading] = useState(false);
                    const [error, setError] = useState<string | null>(null);

                    const fetchPosts = async () => {
                      try {
                        setLoading(true);
                        const response = await fetch('/api/posts');
                        const data = await response.json();
                        setPosts(data);
                      } catch (err) {
                        setError('Failed to fetch posts');
                      } finally {
                        setLoading(false);
                      }
                    };

                    return (
                      <PostsContext.Provider value={{
                        posts, loading, error, fetchPosts
                      }}>
                        {children}
                      </PostsContext.Provider>
                    );
                  }

Redux Posts

Redux Implementation


                  export const fetchPosts = createAsyncThunk(
                    'posts/fetchPosts',
                    async () => {
                      const response = await fetch('/api/posts');
                      return response.json();
                    }
                  );

                  const postsSlice = createSlice({
                    name: 'posts',
                    initialState: {
                      posts: [],
                      loading: false,
                      error: null,
                    },
                    reducers: {},
                    extraReducers: (builder) => {
                      builder
                        .addCase(fetchPosts.pending, (state) => {
                          state.loading = true;
                          state.error = null;
                        })
                        .addCase(fetchPosts.fulfilled, (state, action) => {
                          state.posts = action.payload;
                          state.loading = false;
                        })
                        .addCase(fetchPosts.rejected, (state) => {
                          state.loading = false;
                          state.error = 'Failed to fetch posts';
                        });
                    },
                  });

Zustand Posts

Zustand Implementation


                  interface PostsStore {
                    posts: Post[];
                    loading: boolean;
                    error: string | null;
                    fetchPosts: () => Promise<void>;
                  }

                  export const usePostsStore = create<PostsStore>((set) => ({
                    posts: [],
                    loading: false,
                    error: null,
                    fetchPosts: async () => {
                      try {
                        set({ loading: true, error: null });
                        const response = await fetch('/api/posts');
                        const data = await response.json();
                        set({ posts: data, loading: false });
                      } catch (err) {
                        set({ error: 'Failed to fetch posts', loading: false });
                      }
                    },
                  }));