Skip to content

Quick React JS Intro

Fraser McCallum edited this page Mar 3, 2022 · 1 revision

In This Guide:

  • Quick Intro
  • Components
  • Props
  • Hooks (state and effect)

Quick Intro

From JavaScript Ecosystem Introduction

React is a JS framework. Browsers have a DOM, or document object model, which essentially represents the HTML structure of a webpage. React works by using a Virtual DOM, another DOM that we can easily manipulate using JavaScript. React then updates the real DOM based on what changes happened to the virtual DOM.

React uses a language called JSX, or TSX for typescript. JSX supports any normal JavaScript code, but also supports the inclusion of HTML like tags inside of the JavaScript code. This is what allows us to write the HTML like elements inside of the JavaScript.

One nice part of JSX is that it allows us to include JavaScript inside the HTML-like parts through the use of curly braces:

const text = "Hello World"
const element = <h1>{text}</h1>;

Components

In order to make the most out of React, we use components. Components are essentially classes or functions of JSX that we can then use inside other components. So for example, we might have a search page component, that contains a search bar component, a button component and another component where the results are listed.

Traditionally, classes were used to create components. In more recent versions, the introduction of hooks made it possible to write many more components as functions. Here, we prefer the use of functional components.

class Welcome extends React.Component {
  render() {
    return <h1>Hello!</h1>;
  }
}
const Welcome: React.FC = () => {
  return <h1>Hello!</h1>;
}

We can then use our components inside the JSX of other components:

const Page: React.FC = () => {
  return (
    <>
      <Welcome />
      <h1>This is my website!</h1>
    </>
  );
};

Props

Props is short for properties. Properties are essentially the inputs to our React components.

💡 Components should never attempt to modify the props they are given. They are read-only.

When using TypeScript functional components, we can explicitly define the props our component needs:

interface WelcomeProps {
	name: string;
	age?: number;
}

In TypeScript, we can use the ? to denote its property as an optional parameter (it's just shorthand for age: number | undefined).

We can then use that interface when defining our component:

const Welcome: React.FC<WelcomeProps> = ({ name, age }) => {
  return <h1>Hello {name}!</h1>;
};

When we use the component, we need to pass in its required props:

const Page: React.FC = () => {
  return (
    <>
      <Welcome name="Fred" />
      <h1>This is my website!</h1>
    </>
  );
};

All React functional components have an optional children prop. The children prop is what is passed between the opening and closing tag. In the example above, the Welcome component has no children. the h1 component has 'This is my website!' as its child.

React will rerender the component if the value of the props changes. Although props are readonly, they come from the parent, where they might be created as normal state variables. In this case, the parent may change the value, which will then change the value of the prop in the child, which will cause a rerender.

💡 In JavaScript, we can pass functions as parameters to components. Typically these are called 'callback functions', functions that are called when some event occurs. This is commonly used when dealing with events like button clicks. A component may have a button, but doesn't know what to do when that button is clicked. Instead, we tell it to execute a function in its props. The parent component will then pass the function to execute when creating the child component.

Hooks

React functional components have many 'hooks'. Here we will just look at the two most important - Effect and State.

State

State is used to create internal state of a component. React will rerender the component if the state change has meaningful effects.

To create state, we can use the following inside a functional component:

const [money, setMoney] = useState<number>(0);

money will contain a read-only variable representing some state.

setMoney is a function that we can use to update the value, i.e. by going setMoney(10)

The value inside useState<number>() is the initial value.

The type inside the angle brackets represents the type of the state. This can be omitted if the type can be inferred from the default state. If it cannot be, then it needs to be included. (In this case, 0 is obviously a number, so it doesn't need to be included).

💡 State should only ever be updated using the set function. React cannot be aware of state changes in any other way. This means, for example, if your state is an array, you can't just push elements to an array. Instead, set the state to be a new array with the changes you want applied.

Effect

Effects listen for changes in certain values, and then execute a function when these changes occur. There are three cases we can listen for:

  • Any update in the component
  • Any update in certain variables
  • When the component is created, and when it is unmounted

A basic useEffect (from React documentation):

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]);

We pass an anonymous function into use effect, which will run whenever an update occurs. That last argument down the bottom, [count], is how we determine which of the 3 behaviors from above we use. It's called the dependency array.

  • If we pass no second argument, it will run after every update.
  • If we pass in a list of variables, the function will run when any of those variables update.
  • If we pass an empty array, the function will run when the component is created.

Now lets look at cleanup:

const App: React.FC = () => {
  const [count, setCount] = useState(0);
  const [otherCount, setOtherCount] = useState(0);

  useEffect(() => {
    console.log(`${count}, ${otherCount}`);
    return () => {
      console.log("Cleanup");
    };
  });

  return (
    <div className="App">
      <div className="flex flex-col">
        <button onClick={() => setCount(count + 1)}>Click Me!</button>
        <button onClick={() => setOtherCount(otherCount + 1)}>Click Other Me!</button>
      </div>
    </div>
  );
};

In this example, we have a button that increments count by one every time we click it. We also have another button that increments another counter every time we click it. Seems simple enough. Let's take a look at the Effect hook.

The function logs the value of the two counts whenever the component updates. We also return a function. This returned function is called a cleanup function. This will run both before the component unmounts, and before the effect function runs in subsequent changes. So with that in mind:

  • With no second argument (no dependency array), when the component is mounted and every time a button is pressed, the effect function will run. Cleanup will be printed before the effect runs, except for the first time, or when the component is unmounted:
image
  • With an empty dependency array, the useEffect will only run when the component is mounted. The cleanup will only run when the component is unmounted:
image

Clicking the buttons does not cause the effect to run

  • With only count in the dependency array, the effect will only run when the component is mounted, and when the first button is clicked. The cleanup will run before the useEffect runs, or when the component is unmounted:
image

As you can see, I clicked the second button 9 times, but the effect didn't run until I clicked the first one again.

Conclusion

That's a pretty decent look at most of the React fundamentals. There's a lot more stuff but its a lot more niche. For more details, the Official React Documentation is very good, and covers everything here in more detail.

Clone this wiki locally