Automattic / Automattic/liveblog

Migrate React class components to functional components with hooks

Open
#796 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
PHP
Stars
313
Forks
129
Avg merge
18h 33m
Merged PRs (30d)
1

Description

## Summary

Convert the remaining React class components to functional components using hooks. This modernises the codebase and provides several benefits.

## What are Hooks?

Hooks (introduced in React 16.8, 2019) let you use state and lifecycle features in functional components instead of classes. They're now the recommended approach.

```javascript
// Before: Class component
class EditorContainer extends Component {
constructor(props) {
super(props);
this.state = { authors: [] };
}

componentDidMount() {
this.loadAuthors();
}

render() {
return ;
}
}

// After: Functional component with hooks
function EditorContainer() {
const [authors, setAuthors] = useState([]);

useEffect(() => {
loadAuthors().then(setAuthors);
}, []);

return ;
}
```

## Benefits

1. **Less code** - Typically 30-50% fewer lines (no constructor, no `this` binding, no lifecycle method boilerplate)
2. **Easier to understand** - Logic is colocated instead of spread across lifecycle methods
3. **Reusable logic** - Custom hooks can share stateful logic between components
4. **Better TypeScript support** - Functional components have simpler type signatures
5. **Performance** - Hooks enable fine-grained memoisation with `useMemo`/`useCallback`
6. **Testing** - Easier to test (no enzyme shallow rendering issues)

## Drawbacks / Considerations

1. **Learning curve** - Different mental model (effects vs lifecycles)
2. **Existing tests** - May need updates if they rely on class instance methods
3. **Dependency arrays** - `useEffect` dependencies can be tricky to get right
4. **No `this`** - Can't access instance methods (but this is usually fine)

## Components to Migrate

| Component | Lines | Complexity | Notes |
|-----------|-------|------------|-------|
| `AppContainer` | ~80 | Medium | Entry point, config loading |
| `EditorContainer` | ~350 | High | Most complex, many methods |
| `EntryContainer` | ~100 | Medium | Entry display, edit mode |
| `PreviewContainer` | ~50 | Low | Simple preview |
| `EventsContainer` | ~60 | Low | Key events |
| `PaginationContainer` | ~40 | Low | Load more |

**Already using hooks:** `LexicalEditor` (new implementation)

## Approach

1. Start with simplest components (`PaginationContainer`, `PreviewContainer`)
2. Create custom hooks for shared logic (`useEntries`, `usePolling`)
3. Migrate complex components last (`EditorContainer`)
4. Update tests as components are converted

## References

- [React Hooks documentation](https://react.dev/reference/react)
- [Migrating from classes](https://react.dev/reference/react/Component#alternatives)

Contributor guide

Open the contributing guide

Research direction

Start with the listed PaginationContainer and PreviewContainer components, then inspect their existing tests and the already-hook-based LexicalEditor for project conventions. Follow the proposed order, identify shared logic for useEntries and usePolling, and update tests as each component is converted. Done means all six listed class components use functional components with hooks and their tests pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.