import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);
  };

  const decrement = () => {
    setCount(count - 1);
  };

  return (
    <div>
      <h2>Counter</h2>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};

export default Counter;

State is data used and managed by components. Components re-render whenever there is a change.

import React, { useState } from 'react';

function Product() {
  const [productName, setProductName] = useState('iPhone 12');
  const [price, setPrice] = useState(999);
  const [inStock, setInStock] = useState(true);
  const [reviews, setReviews] = useState([
    { id: 1, text: 'Great product!', rating: 5 },
    { id: 2, text: 'Average quality', rating: 3 },
  ]);

  // ...

  return (
    // JSX rendering and component logic
  );
}

Can use multiple hooks that are seperate from one another, easier to manage and work with.

const [currentState, setCurrentState] = useState("startingState"); 

<button onClick={() => setCurrentState("newState")}></button> 

SetCurrentState is used to update CurrentState.

import React, { useState } from 'react';

const Toggler = () => {
  const [isOn, setIsOn] = useState(false);

  const handleToggle = () => {
    setIsOn(!isOn);
  };

  return (
    <div>
      <button onClick={handleToggle}>{isOn ? 'ON' : 'OFF'}</button> 
      <h3>{isOn ? 'The toggle is ON' : 'The toggle is OFF'}</h3>
    </div>
  );
};

export default Toggler;

Using ! not operator to make an on and off switch. Returns opposite of state.

import React, { useState } from 'react';

function MyComponent() {
  const [items, setItems] = useState([]);

  const addItem = () => {
    setItems([...items, `Item ${items.length + 1}`]);
  };

  const deleteItem = (index) => {
    const updatedItems = items.filter((item, i) => i !== index);
    setItems(updatedItems);
  };

  return (
    <div>
      <button onClick={addItem}>Add Item</button>
      <ul>
        {items.map((item, index) => (
          <li key={index}>
            {item}
            <button onClick={() => deleteItem(index)}>Delete</button> 
          </li>
        ))}
      </ul>
    </div>
  );
}

export default MyComponent;

Arrays can be used as state. Use array methods such as map, filter, forEach, and so on to work these arrays.

const [count, setCount] = useState(0);
 
const increment = () => setCount(prevCount => prevCount + 1); 

To use the value from the current or previous state pass in a callback with a parameter in state setter.

import React, { useState } from 'react';

const App = () => {
  const [formData, setFormData] = useState({ name: '', email: '' }); 

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

  return (
    <div>
      <input
        type="text"
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="Name"
      />
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="Email"
      />
      <h3>Name: {formData.name}</h3>
      <h3>Email: {formData.email}</h3>
    </div>
  );
};

export default App;

Objects can be used as state. Match property name to replace only that key:value pair when updating state.