Skip to content

neritan/react2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

React.js Lessons Plan

1. Forms in React

Lesson: Controlled Components and Form Handling

  • Creating forms in React
  • Controlled vs uncontrolled components
  • Handling form submissions
  • Form validation
  • Using the useState hook for form state
function SimpleForm() {
  const [formData, setFormData] = useState({
    username: '',
    email: ''
  });

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

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('Form submitted:', formData);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="username"
        value={formData.username}
        onChange={handleChange}
      />
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

2. Promises in JavaScript/React

Lesson: Understanding and Using Promises

  • What are promises?
  • Promise states (pending, fulfilled, rejected)
  • .then() and .catch() syntax
  • Async/await syntax
  • Error handling with promises
// Basic promise example
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = Math.random() > 0.5;
      if (success) {
        resolve('Data fetched successfully!');
      } else {
        reject('Error fetching data');
      }
    }, 1000);
  });
};

// Using in React component
function PromiseExample() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchData()
      .then(result => setData(result))
      .catch(err => setError(err));
  }, []);

  return (
    <div>
      {error && <p>Error: {error}</p>}
      {data && <p>Data: {data}</p>}
      {!error && !data && <p>Loading...</p>}
    </div>
  );
}

3. Introduction to REST APIs

What is an API? Technically speaking, API stands for Application Programming Interface. This sounds a little mysterious, so let's dig into it a little more. If you have a program, you may want it to communicate with another program that is written in a different technology, tech stack, etc. So, generally speaking, an API is the interface that allows one program/application to communicate with another. Think of it as a bridge. You can have two separate terrains, but an API is the bridge between the two.

Many times you will hear the term "RESTful API" or "REST API." A RESTful API, specifically, is an API that communicates among and between web services. These APIs follow a certain set of rules that make sure it is easy for people to implement them. By following a consistent set of conventions, learning different RESTful APIs will become quite easy and streamlined.

Lesson: REST API Fundamentals

  • What is a REST API?
  • HTTP methods (GET, POST, PUT, DELETE)
  • Endpoints and resources
  • Status codes
  • Request/response format (typically JSON)
  • API documentation
// Example REST API structure
const api = {
  // Get all items
  getItems: () => fetch('/api/items'),
  
  // Get single item
  getItem: (id) => fetch(`/api/items/${id}`),
  
  // Create new item
  createItem: (data) => fetch('/api/items', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  }),
  
  // Update item
  updateItem: (id, data) => fetch(`/api/items/${id}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  }),
  
  // Delete item
  deleteItem: (id) => fetch(`/api/items/${id}`, { method: 'DELETE' })
};

4. useEffect for API Calls

Lesson: Fetching Data with useEffect

  • Why useEffect for API calls?
  • Dependency array
  • Cleanup functions
  • Loading states
  • Error handling
function DataFetcher() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    // Cleanup function if needed
    return () => {
      // Cancel ongoing requests if component unmounts
    };
  }, []); // Empty dependency array means run once on mount

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
}

5. Consuming APIs with PokeAPI

Lesson: Practical API Consumption with PokeAPI

  • Understanding the PokeAPI endpoints
  • Fetching data from a real-world API
  • Displaying API data in components
  • Pagination with offset/limit
function PokemonList() {
  const [pokemon, setPokemon] = useState([]);
  const [loading, setLoading] = useState(true);
  const [offset, setOffset] = useState(0);
  const limit = 10;

  useEffect(() => {
    const fetchPokemon = async () => {
      setLoading(true);
      try {
        const response = await fetch(
          `https://pokeapi.co/api/v2/pokemon?offset=${offset}&limit=${limit}`
        );
        const data = await response.json();
        setPokemon(data.results);
      } catch (error) {
        console.error('Error fetching Pokemon:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchPokemon();
  }, [offset]);

  return (
    <div>
      <h1>Pokemon List</h1>
      {loading ? (
        <p>Loading...</p>
      ) : (
        <ul>
          {pokemon.map((p) => (
            <li key={p.name}>{p.name}</li>
          ))}
        </ul>
      )}
      <button onClick={() => setOffset(prev => Math.max(0, prev - limit))}>
        Previous
      </button>
      <button onClick={() => setOffset(prev => prev + limit)}>
        Next
      </button>
    </div>
  );
}

6. Axios for API Requests

Lesson: Using Axios Instead of Fetch

  • Why use Axios?
  • Installing and setting up Axios
  • GET, POST, PUT, DELETE with Axios
  • Interceptors
  • Error handling with Axios
import axios from 'axios';

function AxiosExample() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchPosts = async () => {
      setLoading(true);
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
        setPosts(response.data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchPosts();
  }, []);

  const addPost = async (title, body) => {
    try {
      const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
        title,
        body,
        userId: 1
      });
      setPosts(prev => [response.data, ...prev]);
    } catch (err) {
      setError(err.message);
    }
  };

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <button onClick={() => addPost('New Post', 'This is the body')}>
        Add Post
      </button>
      <ul>
        {posts.slice(0, 5).map(post => (
          <li key={post.id}>
            <h3>{post.title}</h3>
            <p>{post.body}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

7. Consuming APIs - Advanced Patterns

Lesson: Advanced API Consumption Techniques

  • Custom hooks for API calls
  • Handling pagination
  • Debouncing search requests
  • Caching responses
  • Error boundaries
  • Loading states and skeletons
// Custom hook for API calls
function useApi(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(url);
        setData(response.data);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [url]);

  return { data, loading, error };
}

function PokemonDetail({ name }) {
  const { data: pokemon, loading, error } = useApi(
    `https://pokeapi.co/api/v2/pokemon/${name}`
  );

  if (loading) return <div>Loading {name}...</div>;
  if (error) return <div>Error loading {name}</div>;

  return (
    <div>
      <h2>{pokemon.name}</h2>
      <img
        src={pokemon.sprites.front_default}
        alt={pokemon.name}
      />
      <h3>Abilities:</h3>
      <ul>
        {pokemon.abilities.map((ability) => (
          <li key={ability.ability.name}>{ability.ability.name}</li>
        ))}
      </ul>
    </div>
  );
}

Additional Resources

  1. React Documentation: https://reactjs.org/docs/forms.html
  2. PokeAPI Documentation: https://pokeapi.co/
  3. Axios Documentation: https://axios-http.com/docs/intro
  4. MDN Fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
  5. JavaScript Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Would you like me to expand on any of these lessons or provide additional examples for specific scenarios?

About

Lesson for React2

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published