# FP in Frontend and Data Pipelines — Functional Programming Concepts

Source: https://www.geekswithgeeks.com/en/functional-programming/pr-frontend

> Pure components, reducers and transformation chains.

## Pure views and reducers

React's documentation asks components to be **pure**: given the same props, state and context they should return the same JSX and not mutate pre-existing objects during rendering; side effects belong in event handlers or `useEffect`. State updates must be immutable so React can detect changes. A **reducer** is a pure function `(state, action) => newState`, used by `useReducer` and by Redux, whose reducers must not mutate state or perform side effects (Redux Toolkit uses Immer to allow mutation-style code safely). Data pipelines follow the same shape: extract, then a chain of pure, testable transformations (map, filter, group, aggregate), then load. Spark, pandas method chaining and stream processors all encourage this style.

## A reducer for a todo list

Pure, immutable, exhaustively matched.

```typescript
type Todo = { id: number; text: string; done: boolean };
type Action =
  | { type: 'added'; id: number; text: string }
  | { type: 'toggled'; id: number }
  | { type: 'removed'; id: number };

function todosReducer(state: readonly Todo[], action: Action): Todo[] {
  switch (action.type) {
    case 'added':
      return [...state, { id: action.id, text: action.text, done: false }];
    case 'toggled':
      return state.map(t => (t.id === action.id ? { ...t, done: !t.done } : t));
    case 'removed':
      return state.filter(t => t.id !== action.id);
    default: {
      const unreachable: never = action;
      return unreachable;
    }
  }
}

// In a React component: const [todos, dispatch] = useReducer(todosReducer, []);
// Testing needs no rendering: todosReducer([], { type: 'added', id: 1, text: 'x' })
```

## Generate ids outside the reducer

Creating ids with `Date.now()` or `crypto.randomUUID()` inside a reducer makes it impure. Create them in the event handler and put them in the action.

**Quiz:** What must a Redux or useReducer reducer avoid?

- [x] Mutating the existing state and performing side effects
- [ ] Returning a new object
- [ ] Using a switch statement
- [ ] Accepting an action argument

*Answer:* Mutating the existing state and performing side effects. Reducers are pure functions of state and action.
