DEV Community

Sianwa Atemi
Sianwa Atemi

Posted on • Edited on

Day 1 - 10

Day 1 and 2: Created a simple Todo list

I have a basic knowledge in React and attempted to use that to create a todo list. I learnt how to use React hooks, Portals, the context api (useContext) and other main concepts. The code can be found here Github repo. The live demo here.

Screenshot of the todo app


Day 3: Optimization in react

React.memo
I learnt that this is a higher order component (a function that takes a component and returns a new component) that is used when your component renders the same value and you want to improve performance.

const Book = (props) => {
  // rendering using props
};

export default React.memo(Demo);
Enter fullscreen mode Exit fullscreen mode

Note: If props are passed by reference this will not prevent re-renders, like if an object is passed.

useCallback()
The useCallback() hook is useful when passing callbacks to optimized components. This can be a solution to the problem above. According to the documentation useCallback receives a callback and dependencies that when changed return a memoized version of the callback

Lets say the props in the Book component above receive an object that sometimes changes, like an array of written reviews. The Book's parent component can pass the changing object in a useCallback hook that will result in the Book only getting rendered when the array changes.

const Parent = () => {
  // state that detects a change in the review
  const [reviewState, setReview] = useState();

  // Lets assume this function handles the change of review somewhere
  const handlChange = useCallback(() => {
    // setReview() to change the reviewstate
  }, [reviewState]);

  // Book will rerender only when review changes
  return (
    <>
      <Book reviews={reviewState} />
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

It will probably look different in the real world but this is just a brief explanation of what I learnt.

useMemo()
This is a hook that returns a memoized value. It is used to avoid rerendering expensive calculations. It accepts a callback and dependencies that when changed recompute the memoized value.

const heavyCalculation = useMemo(() => {
  someHeavyCalculation(x, y);
}, [x, y]);
Enter fullscreen mode Exit fullscreen mode

Note: If no dependencies (x and y in the example above) are provided, a new value will be computed on every render.

Today I mostly read the docs and watched some videos to understand these three concepts.


Day 4: Error Boundaries

I learnt that Error boundaries are class components that catch errors in their child components and display fallback UIs. It's kind of like a try catch block but for jsx. To create an error boundary add the componentDidCatch() method in your class component.

class ErrorBoundary extends React.Component {
  constructor() {
    super();
    this.state = { hasError: false };
  }

  componentDidCatch() {
    // change error state
    return (this.state = { hasError: true });
  }

  render() {
    if (this.state.hasError) {
      return <p>Something went wrong.</p>;
    }

    return this.props.children;
  }
}
Enter fullscreen mode Exit fullscreen mode
// The error can then be displayed in a regular component
<ErrorBoundary>
  <SomeComponent />
</ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

Day 5 and 6: Sending HTTP requests

I learnt how to send HTTP requests in React. I built a small project with unsplash api where users can search for images and get results displayed to them. The image loading could be made a little bit faster by various optimization techniques, this is a feature I am yet to implement. Here is the live demo

Gallery app screenshot


Day 7: Using custom hooks

I learnt that a custom hook is a JavaScript function whose name starts with "use" and may call other hooks, this is according to the React documentation.

Why would you want to use a custom hook? Well, if you have repeated logic in your components a custom hook could come in handy. Below is a scenario where a custom hook would be of use.

Lets say you have an application that fetches a list of usernames from a database and that functionality is to be used in multiple components.

const HomePage = (props) => {
  const [users, setUsers] = useState(null);

  // Instead of writing this code in multiple components we can make it leaner by using a custom hook
  useEffect(() => {
    const data = fetchFromDB(props.id);
    setUser(data);
  }, []);
};
Enter fullscreen mode Exit fullscreen mode

We can create a custom hook that does this and call it where it is needed. Note that a custom hook must start with "use"

import React, { useState } from "react";

const useFetchUsers = (userId) => {
  const [users, setUsers] = useState(null);

  useEffect(() => {
    const data = fetchFromDB(userId);
    setUsers(data);
  }, []);

  return users;
};

export default useFetchUsers;
Enter fullscreen mode Exit fullscreen mode
// import useFetchUsers

const HomePage = (props) => {
  const users = useFetchUsers(props.id);

  return (
    <div>
      {users.map((data) => {
        <Table key={data.id} name={data.name} />;
      })}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

The useFetchNames hook can now be used in multiple components 👍🏾


Day 8: Forms in React

I took a 2 day break, however, today I did some light work and read about controlledcomponents. What I learnt is that in a controlled component, the form elements data is handled by the React component and not the DOM, the data is then stored in the components state, unlike an uncontrolled component that stores its own state internally and to get the value of an input you query the DOM using a ref to find its current value.

// Uncontrolled component values are accessed with refs
<input type="text" value="value" ref={inputRef} />

// Controlled components values are handled by the component
<input type="text" value={name} onChange={changeHandler} />
Enter fullscreen mode Exit fullscreen mode

Using controlled components means writing a bit more code, especially when it comes to validation as you have to validate each and every input element but it gives you flexibility to pass values to other UI elements and reset them too. A workaround to this is to use custom hooks to handle your validations in a cleaner way or using a library like Formik which I am yet to use.


Day 9: Practice project

The goal is to create a very simple chat application utilizing most of the concepts that I have learnt in this first week.

User stories

  • User is prompted to enter username and room name to join a chat room.
  • User can see input field and send message on submit.
  • User can see who has joined or left the chat.

Day 10: Practice project(update)

The project is taking longer than expected 😅. I had to learn some socket-io and better ways to use it in React to manage its events. I shall update when I am done

(update)

I managed to create a Minimum Viable Product (MVP) that has the chat functionality working, it was quite challenging but I managed to do it. What made it hard was that the application was creating multiple socket events and connections but after reading this blog my work was much more easier.

Things to improve

  • Add Media queries to the app (It looks really bad on mobile). I shall update this.
  • Error handling (There is none at the moment)
  • Prevent duplicate usernames in chat.
  • Add encryption to the chat.

Here is the source code for the frontend and the backend which I heavily borrowed from this article.

Here is the MVP live demo with no error handling tentatively 😬.

Top comments (0)