# useState Hook Cheatsheet

## Basic Syntax

```jsx
import { useState } from 'react';

function MyComponent() {
  const [state, setState] = useState(initialValue);
  
  // ...
}
```

## Key Concepts

- **State Declaration**: `const [state, setState] = useState(initialValue)`
- **Read State**: Use the first variable (`state`) to read the current state value
- **Update State**: Use the second variable (`setState`) to update the state value
- **Initial Value**: The value passed to `useState()` is only used during the first render

## Common Patterns

### Basic State Updates

```jsx
// Direct update
setState(newValue);

// Update based on previous state (recommended for dependent updates)
setState(prevState => prevState + 1);
```

### Working with Object State

```jsx
const [user, setUser] = useState({ name: '', email: '' });

// ❌ INCORRECT: Direct mutation
user.name = 'John'; // Don't do this!

// ✅ CORRECT: Replace the entire object
setUser({ ...user, name: 'John' });
```

### Working with Array State

```jsx
const [items, setItems] = useState([]);

// Add item to array
setItems(prevItems => [...prevItems, newItem]);

// Remove item from array
setItems(prevItems => prevItems.filter(item => item.id !== idToRemove));

// Update item in array
setItems(prevItems => 
  prevItems.map(item => 
    item.id === idToUpdate ? { ...item, name: 'Updated' } : item
  )
);
```

### Form Input State

```jsx
const [inputValue, setInputValue] = useState('');

// Event handler for input changes
const handleChange = (e) => {
  setInputValue(e.target.value);
};

// Usage in JSX
<input value={inputValue} onChange={handleChange} />
```

### Multiple Input Form

```jsx
const [formData, setFormData] = useState({
  firstName: '',
  lastName: '',
  email: ''
});

const handleChange = (e) => {
  const { name, value } = e.target;
  setFormData(prevData => ({
    ...prevData,
    [name]: value
  }));
};

// Usage in JSX
<input 
  name="firstName"
  value={formData.firstName}
  onChange={handleChange}
/>
```

## Best Practices

### 1. Use Multiple State Variables for Unrelated Data

```jsx
// ✅ GOOD: Separate state variables for unrelated data
const [name, setName] = useState('');
const [age, setAge] = useState(0);

// ❌ NOT IDEAL: Single object for unrelated data
const [person, setPerson] = useState({ name: '', age: 0 });
```

### 2. Use a Single State Object for Related Data

```jsx
// ✅ GOOD: Single object for related form fields
const [formData, setFormData] = useState({
  username: '',
  password: '',
  email: ''
});
```

### 3. Always Use the Callback Form When Updates Depend on Previous State

```jsx
// ❌ RISKY: May not use latest state value
setCount(count + 1);

// ✅ SAFE: Always uses latest state value
setCount(prevCount => prevCount + 1);
```

### 4. Avoid Redundant State

```jsx
// ❌ BAD: Derived state can lead to bugs
const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');
const [fullName, setFullName] = useState('John Doe'); // Redundant!

// ✅ GOOD: Compute derived values during render
const [firstName, setFirstName] = useState('John');
const [lastName, setLastName] = useState('Doe');
const fullName = `${firstName} ${lastName}`; // Computed value
```

## Initialization with Complex Values

```jsx
// ❌ NOT IDEAL: Function runs on every render
const [data, setData] = useState(createExpensiveObject());

// ✅ GOOD: Lazy initialization, function runs only once
const [data, setData] = useState(() => createExpensiveObject());
```

## Common Gotchas

### 1. State Updates are Asynchronous

State updates don't happen immediately. React batches updates for performance.

```jsx
// This may not log the updated value
setState(newValue);
console.log(state); // Still the old value!

// Use useEffect to react to state changes
useEffect(() => {
  console.log(state); // Now updated!
}, [state]);
```

### 2. State Updates Don't Merge Objects (unlike class components)

```jsx
// Class component (merges objects)
this.setState({ name: 'John' }); // Only updates name

// Functional component with useState (replaces objects)
setUser({ name: 'John' }); // Removes all other properties!
setUser(prevUser => ({ ...prevUser, name: 'John' })); // Correct way
```

### 3. State Updates Trigger Re-renders

Every time you call a state setter function, React will re-render the component (unless the new state is identical to the previous state as determined by Object.is()).

## When to Use Other Hooks Instead

- **useReducer**: When state logic is complex or when next state depends on previous state
- **useContext**: When state needs to be accessed by many components
- **useRef**: When you need a mutable value that doesn't trigger re-renders
