style: format all files with prettier

This commit is contained in:
Seth Hobson
2026-01-19 17:07:03 -05:00
parent 8d37048deb
commit 56848874a2
355 changed files with 15215 additions and 10241 deletions

View File

@@ -24,12 +24,14 @@ Master React version upgrades, class to hooks migration, concurrent features ado
**Breaking Changes by Version:**
**React 17:**
- Event delegation changes
- No event pooling
- Effect cleanup timing
- JSX transform (no React import needed)
**React 18:**
- Automatic batching
- Concurrent rendering
- Strict Mode changes (double invocation)
@@ -39,6 +41,7 @@ Master React version upgrades, class to hooks migration, concurrent features ado
## Class to Hooks Migration
### State Management
```javascript
// Before: Class component
class Counter extends React.Component {
@@ -46,13 +49,13 @@ class Counter extends React.Component {
super(props);
this.state = {
count: 0,
name: ''
name: "",
};
}
increment = () => {
this.setState({ count: this.state.count + 1 });
}
};
render() {
return (
@@ -67,7 +70,7 @@ class Counter extends React.Component {
// After: Functional component with hooks
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
const [name, setName] = useState("");
const increment = () => {
setCount(count + 1);
@@ -83,6 +86,7 @@ function Counter() {
```
### Lifecycle Methods to Hooks
```javascript
// Before: Lifecycle methods
class DataFetcher extends React.Component {
@@ -155,6 +159,7 @@ function DataFetcher({ id }) {
```
### Context and HOCs to Hooks
```javascript
// Before: Context consumer and HOC
const ThemeContext = React.createContext();
@@ -175,11 +180,7 @@ class ThemedButton extends React.Component {
function ThemedButton({ children }) {
const { theme } = useContext(ThemeContext);
return (
<button style={{ background: theme }}>
{children}
</button>
);
return <button style={{ background: theme }}>{children}</button>;
}
// Before: HOC for data fetching
@@ -188,7 +189,7 @@ function withUser(Component) {
state = { user: null };
componentDidMount() {
fetchUser().then(user => this.setState({ user }));
fetchUser().then((user) => this.setState({ user }));
}
render() {
@@ -218,52 +219,55 @@ function UserProfile() {
## React 18 Concurrent Features
### New Root API
```javascript
// Before: React 17
import ReactDOM from 'react-dom';
import ReactDOM from "react-dom";
ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(<App />, document.getElementById("root"));
// After: React 18
import { createRoot } from 'react-dom/client';
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById('root'));
const root = createRoot(document.getElementById("root"));
root.render(<App />);
```
### Automatic Batching
```javascript
// React 18: All updates are batched
function handleClick() {
setCount(c => c + 1);
setFlag(f => !f);
setCount((c) => c + 1);
setFlag((f) => !f);
// Only one re-render (batched)
}
// Even in async:
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
setCount((c) => c + 1);
setFlag((f) => !f);
// Still batched in React 18!
}, 1000);
// Opt out if needed
import { flushSync } from 'react-dom';
import { flushSync } from "react-dom";
flushSync(() => {
setCount(c => c + 1);
setCount((c) => c + 1);
});
// Re-render happens here
setFlag(f => !f);
setFlag((f) => !f);
// Another re-render
```
### Transitions
```javascript
import { useState, useTransition } from 'react';
import { useState, useTransition } from "react";
function SearchResults() {
const [query, setQuery] = useState('');
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
@@ -288,8 +292,9 @@ function SearchResults() {
```
### Suspense for Data Fetching
```javascript
import { Suspense } from 'react';
import { Suspense } from "react";
// Resource-based data fetching (with React 18)
const resource = fetchProfileData();
@@ -320,6 +325,7 @@ function ProfileTimeline() {
## Codemods for Automation
### Run React Codemods
```bash
# Install jscodeshift
npm install -g jscodeshift
@@ -342,22 +348,25 @@ npx codemod react/hooks/convert-class-to-function src/
```
### Custom Codemod Example
```javascript
// custom-codemod.js
module.exports = function(file, api) {
module.exports = function (file, api) {
const j = api.jscodeshift;
const root = j(file.source);
// Find setState calls
root.find(j.CallExpression, {
callee: {
type: 'MemberExpression',
property: { name: 'setState' }
}
}).forEach(path => {
// Transform to useState
// ... transformation logic
});
root
.find(j.CallExpression, {
callee: {
type: "MemberExpression",
property: { name: "setState" },
},
})
.forEach((path) => {
// Transform to useState
// ... transformation logic
});
return root.toSource();
};
@@ -368,38 +377,38 @@ module.exports = function(file, api) {
## Performance Optimization
### useMemo and useCallback
```javascript
function ExpensiveComponent({ items, filter }) {
// Memoize expensive calculation
const filteredItems = useMemo(() => {
return items.filter(item => item.category === filter);
return items.filter((item) => item.category === filter);
}, [items, filter]);
// Memoize callback to prevent child re-renders
const handleClick = useCallback((id) => {
console.log('Clicked:', id);
console.log("Clicked:", id);
}, []); // No dependencies, never changes
return (
<List items={filteredItems} onClick={handleClick} />
);
return <List items={filteredItems} onClick={handleClick} />;
}
// Child component with memo
const List = React.memo(({ items, onClick }) => {
return items.map(item => (
return items.map((item) => (
<Item key={item.id} item={item} onClick={onClick} />
));
});
```
### Code Splitting
```javascript
import { lazy, Suspense } from 'react';
import { lazy, Suspense } from "react";
// Lazy load components
const Dashboard = lazy(() => import('./Dashboard'));
const Settings = lazy(() => import('./Settings'));
const Dashboard = lazy(() => import("./Dashboard"));
const Settings = lazy(() => import("./Settings"));
function App() {
return (
@@ -446,12 +455,14 @@ function List<T>({ items, renderItem }: ListProps<T>) {
```markdown
### Pre-Migration
- [ ] Update dependencies incrementally (not all at once)
- [ ] Review breaking changes in release notes
- [ ] Set up testing suite
- [ ] Create feature branch
### Class → Hooks Migration
- [ ] Identify class components to migrate
- [ ] Start with leaf components (no children)
- [ ] Convert state to useState
@@ -461,6 +472,7 @@ function List<T>({ items, renderItem }: ListProps<T>) {
- [ ] Test thoroughly
### React 18 Upgrade
- [ ] Update to React 17 first (if needed)
- [ ] Update react and react-dom to 18
- [ ] Update @types/react if using TypeScript
@@ -470,6 +482,7 @@ function List<T>({ items, renderItem }: ListProps<T>) {
- [ ] Adopt Suspense/Transitions where beneficial
### Performance
- [ ] Identify performance bottlenecks
- [ ] Add React.memo where appropriate
- [ ] Use useMemo/useCallback for expensive operations
@@ -477,6 +490,7 @@ function List<T>({ items, renderItem }: ListProps<T>) {
- [ ] Optimize re-renders
### Testing
- [ ] Update test utilities (React Testing Library)
- [ ] Test with React 18 features
- [ ] Check for warnings in console