Categories
React Tips

React Tips — Data Flow and Pure Components

React is the most-used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to share data between components and speed up rendering with pure components.

Data Flow with Flux

Flux architecture is a way to create a data layer in JavaScript apps. It works by adding the data layer in a centralized data store. Updates to the store are done by dispatching actions to the store which updates the store’s state.

Any component that needs the data can subscribe to the latest updates to the data store to get the relevant state.

This is a good way to organize our data layer structure because it removes the need to share data between components directly. All data is in one place.

This reduces the confusion that arises from sharing data between components, especially if we need to pass data between unrelated components by passing data between a chain of related components.

The most common library for implementing the Flux architecture is with Redux. We can use it by writing the following code:

index.js :

import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import App from "./App";
import { Provider } from "react-redux";

const counter = (state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
};

const store = createStore(counter);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  rootElement
);

App.js :

import React from "react";
import { useSelector, useDispatch } from "react-redux";

export default function App() {
  const count = useSelector(state => state);
  const dispatch = useDispatch();

  return (
    <>
      <button onClick={() => dispatch({ type: "INCREMENT" })}>Increment</button>
      <p>{count}</p>
    </>
  );
}

In the code above, we used the React hooks version of the React-Redux API. First, we created the store with:

const counter = (state = 0, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
};

const store = createStore(counter);

Then we wrap the Provider component around the entry point of our app in index.js . We pass in the store object so that we can access it.

The store is created by first creating the counter reducer, which updates the state . Then we pass in the counter reducer to createStore to create the store.

Then in App , we access the store by using the useDispatch hook so that we can dispatch actions with the returned function. Then we use the useSelector hook to return the state from our store with the callback.

Once we did that, we call dispatch when we click the Increment button. In the dispatch function call, we pass in the type property with the 'INCREMENT' action, which means that the 'INCREMENT' action in the counter reducer will be completed.

Then when we click the Increment, count will update because we updated the store with state + 1 each time the 'INCREMENT' action is dispatched.

Pure Components

Pure components are React components that implement the shouldComponentUpdate method.

The ones that implement shouldComponentUpdate are always class-based components. We can also create components that don’t implement that by returning the result that is derived from the props that are passed in.

In general, a component is pure if the return value of the component is only determined by its input values.

We can create a classed based component and use it as follows:

import React from "react";

class Pecentage extends React.PureComponent {
  render() {
    const { score, total } = this.props;
    return (
      <div>
        <span>{Math.round((score / total) * 100)}%</span>
      </div>
    );
  }
}

export default function App() {
  return <Pecentage score={70} total={100} />;
}

In the code above, we have the Percentage component, which implements React.PureComponent .

It takes 2 props, score and total and we return the percentage point derived from score divided by total .

shouldComponentUpdate is automatically included and it does a shallow comparison of the data, so we don’t need to write one ourselves to do the comparison since both props are numbers. Therefore, React will rerender the component only if the props change in value.

On the other hand, if the props are objects, then we’ll need to implement the method and do the checks ourselves.

It returns the same output given the same input, so it’s a pure component.

Also, we can implement pure function components as follows:

import React from "react";

const Pecentage = ({ score, total }) => {
  return (
    <div>
      <span>{Math.round((score / total) * 100)}%</span>
    </div>
  );
};

We just pass in the props as we need to and it also returns the same output given the same input, so it’s a pure component.

Conclusion

If our apps have multiple components that need to share data, then we need Flux architecture. To implement it, the best way is to use popular existing libraries like Redux.

The pure component has optimizations that are done by React to speed up rendering. They only render if the props change. The change detection is done by shallow comparison.

Categories
React Tips

React Tips — Components and Props

React is one of the most popular libraries for creating front end apps. It can also be used to create mobile apps with React Native.

In this article, we’ll look at the basics of React that we may have missed or forgotten.

Components Can Be Reused Anywhere in Our App

The whole point of creating a React component is that we create a group of elements and components that we can use anywhere in our app.

For instance, we can define our components and use them anywhere as follows:

import React from "react";

const Foo = () => <p>foo</p>;
const Bar = () => <p>bar</p>;

export default function App() {
  return (
    <div className="App">
      <Foo />
      <Bar />
      <Bar />
    </div>
  );
}

In the code above, we created the Foo and Bar components, which we used in our App component.

We can reference them as many times as we want. Although if we reference them more than twice we should use the map method to return multiple instances of a component instead of repeating them everywhere.

For example, if we want to show the Bar component 5 times in App, we can write the following code:

import React from "react";
const Bar = () => <p>bar</p>;

export default function App() {
  return (
    <div className="App">
      {Array(5)
        .fill()
        .map((_, i) => (
          <Bar key={i} />
        ))}
    </div>
  );
}

In the code above, we created an array, fill them with undefined with filland then map all the entries to Bar so that we can display Bar 5 times.

Also, we always have to remember to set the key prop so that React can identify them properly. The key prop’s value for each entry should be a unique value like the array index or another unique ID.

Data Can Be Dynamically Passed to Components with Props

Without props, most components are useless since almost all of them need data for them to be useful.

For instance, we can create a component that takes a prop and use it as follows:

import React from "react";

const names = ["jane", "joe", "alex"];

const Name = ({ name }) => <p>{name}</p>;

export default function App() {
  return (
    <div className="App">
      {names.map((n, i) => (
        <Name key={i} name={n} />
      ))}
    </div>
  );
}

In the code above, we created the Name component which takes the name prop and display it inside the component.

Then we used it by calling map on names to map them name strings in the array into the Name component to render it.

We passed in the name prop with the value n from the names array so the the name property will be populated by the name string from the array.

Therefore, we’ll see:

jane

joe

alex

displayed on the screen.

If we have multiple props, we can use the spread operator to spread them all into props so that we don’t have to write them out all at once.

For instance, we can write the following to spread our props into a component as follows:

import React from "react";

const names = [
  { firstName: "jane", lastName: "smith" },
  { firstName: "john", lastName: "smith" },
  { firstName: "alex", lastName: "jones" }
];

const Name = ({ firstName, lastName }) => (
  <p>
    {firstName} {lastName}
  </p>
);

export default function App() {
  return (
    <div className="App">
      {names.map((n, i) => (
        <Name key={i} {...n} />
      ))}
    </div>
  );
}

In the code above, we have the names array, which has the firstName and lastName properties.

To make our code shorter when we are passing props into the Name component, we spread the properties of each entry as props by using the spread operator as we did in:

<Name key={i} {...n} />

As long as the property and prop names match exactly and in the name nesting level, then they’re spread as props properly.

Since firstName and lastName are all at the top level, we can spread them easily with the spread operator and they’ll be the value of the props with the same name.

Conclusion

React components can be anywhere in our app. They can be referenced as long as they’re defined.

We can pass in data to components via props. This makes them useful. We can pass in props by passing them explicitly in a way that looks like their HTML attributes, or we can use the spread operator to pass in multiple props with the same name all at once.

Categories
React Tips

React Tips — The Basics

React is one of the most popular libraries for creating front end apps. It can also be used to create mobile apps with React Native.

In this article, we’ll go back to the basics and look at basic things that we should be aware of that can let us create React apps easier.

JSX Code are Expressions

When writing React code, we have to remember that JSX code is just JavaScript expressions. This means that they can be used anywhere that JavaScript expressions can be used like assigning them to variables, nesting them, using them as properties of objects, returning them in functions, etc.

For instance, we can do common operations with them as follows:

import React from "react";
const title = <h1>Hello</h1>;

export default function App() {
  return <div className="App">{title}</div>;
}

In the code above, we have the title constant that’s assigned to an h1 element. We then put it inside the App component.

If we remember this, then we won’t have any difficulty with incorporating JSX code in our React app.

JSX Can Be Nested

We can nest JSX elements within each other. For instance, we can nest multiple components within another component as follows:

import React from "react";

export default function App() {
  return (
    <div>
      <p>foo</p>
      <p>bar</p>
    </div>
  );
}

In the code above, we have the div element that wraps around 2 p elements.

We can access child components by the special children prop in our own component. For instance, we can write the following code to do that:

import React from "react";

const Foo = ({ children }) => {
  return <div>{children}</div>;
};

export default function App() {
  return (
    <Foo>
      <p>foo</p>
      <p>bar</p>
    </Foo>
  );
}

In the code above, we have the Foo component that takes the children prop which is rendered in the component by returning it inside a div.

Then in App , we put in 2 p elements inside Foo and lets us display them within the Foo component. This way, we can nest items in our own components with ease.

HTML and JSX are Different

HTML and JSX are different. JSX is a JavaScript code that looks like HTML. As we saw above, the JSX code is just JavaScript in a different form. They shouldn’t be confused with HTML even though they look kind of the same.

Differences include all tags have to be closed and the class attribute in HTML is called className in JSX.

For instance, in HTML, we have tags like img that that don’t close in HTML. We can add an image in HTML by writing the following code:

<img src='https://images.unsplash.com/photo-1565598478542-4dfb41f0e9e2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80' alt='work'>

On the other hand, in JSX, we have to close the tag. Therefore, we write the following:

import React from "react";

export default function App() {
  return (
    <img
      src="https://images.unsplash.com/photo-1565598478542-4dfb41f0e9e2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80"
      alt="work"
    />
  );
}

In the code above, we have a slash at the end of the img tag. This is required rather than optional.

To add the class attribute to an element, we can write the following code in HTML:

<div class='foo'>
  foo
</div>

We added the foo class with the class attribute.

In JSX, we have to write the following code:

import React from "react";

export default function App() {
  return <div className="foo">foo</div>;
}

The className prop lets us set the class attribute of the div element rather than class . This is because class is a reserved word in JavaScript, so it can’t be used as a prop name.

Also, in JavaScript, the className property is the property of a DOM element object that’s used to set the class attribute value.

Therefore, we must remember that the prop to set the class attribute is className in React and JSX.

Components and Props

A React app has components that take props. Props are data that are passed down from a parent to a child.

Props can be any kind of data. They can be objects, primitive values, functions, etc.

If we pass in a function as a prop value, then we can call functions that’s in the parent in the child component.

For instance, we can pass in several props as follows:

import React from "react";

const Button = ({ displayAlert, text }) => {
  return <button onClick={displayAlert}>{text}</button>;
};

export default function App() {
  const displayAlert = () => alert("alert");
  return <Button text="click me" displayAlert={displayAlert} />;
}

In the code above, we passed in a function displayAlert into the Button component, which is a child component for App , then we called it in Button when the button is clicked.

We also pass in the text prop with the value 'click me' to display the text on the button.

Conclusion

JSX is just JavaScript expressions. Therefore, we can put expressions anywhere by writing it just like any other expression.

HTML and JSX are different. They look similar but JSX is JavaScript and HTML is HTML.

Finally, React apps are composed of components which take props. Props are data that are passed in from a parent component to a child and can be any JavaScript data type.

Categories
React Tips

React Tips — Clean Syntax

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to write React components in a clean way.

Toggling Components

We can toggle components by using ternary expressions. For instance, we can write the following code to do that:

import React from "react";

const Foo = () => <p>foo</p>;
const Bar = () => <p>bar</p>;

export default function App() {
  const [toggle, setToggle] = React.useState(false);

  return (
    <>
      <div>
        <button onClick={() => setToggle(toggle => !toggle)}>Toggle</button>
        {toggle ? <Foo /> : <Bar />}
      </div>
    </>
  );
}

In the code above, we have Foo and Bar components that we want to toggle between. We used the ternary expression to do that in the following code:

{toggle ? <Foo /> : <Bar />}

The code above returns Foo or Bar given the value of toggle . Therefore, when we click the Toggle button, the setToggle method is called, and then React renders Foo or Bar depending on whether toggle is true or not.

If we want to toggle a single component on and off, we can write the following code:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  const [toggle, setToggle] = React.useState(false);

  return (
    <>
      <div>
        <button onClick={() => setToggle(toggle => !toggle)}>Toggle</button>
        {toggle ? <Foo /> : undefined}
      </div>
    </>
  );
}

We can put null or undefined in JSX if we don’t want to render anything. Also, we can write:

import React from "react";

const Foo = () => <p>foo</p>;

export default function App() {
  const [toggle, setToggle] = React.useState(false);

  return (
    <>
      <div>
        <button onClick={() => setToggle(toggle => !toggle)}>Toggle</button>
        {toggle && <Foo />}
      </div>
    </>
  );
}

In the code above, we used the && operator to show Foo only when toggle is true .

Destructuring Props and State

Destructuring props and state are great because we can selectively choose which the props and state to render according to our preference.

We can destructure props by writing the following for function components:

import React from "react";

const Person = ({ firstName, lastName, age }) => (
  <p>
    {firstName} {lastName} {age}
  </p>
);

export default function App() {
  return (
    <>
      <div>
        <Person firstName="Jane" lastName="Smith" age={20} />
      </div>
    </>
  );
}

In the code above, we pass in the firstName , lastName , and age props into Person , then we used the destructuring syntax in the parameter of Person to extract the props from the parameters.

Therefore, we see:

Jane Smith 20

displayed on the screen as we pass in the props in App and render them in Person .

For class components, we can destructure props and state as follows:

import React from "react";

class Person extends React.Component {
  render() {
    const { firstName, lastName, age } = this.props;
    return (
      <p>
        {firstName} {lastName} {age}
      </p>
    );
  }
}

export default function App() {
  return (
    <>
      <div>
        <Person firstName="Jane" lastName="Smith" age={20} />
      </div>
    </>
  );
}

In the code above, we have the Person class component, that has the render method. We access the props by using this.props and then we destructure the properties of this.props into their own variables.

Then we render them in the p element. Therefore, we’ll get the same result as before.

Likewise, we can destructure states as follows:

import React from "react";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      posCount: 0,
      negCount: 0
    };
  }

  render() {
    const { posCount, negCount } = this.state;
    return (
      <div>
        <button
          onClick={() => this.setState(count => ({ posCount: posCount + 1 }))}
        >
          Increment
        </button>
        <button
          onClick={() => this.setState(count => ({ negCount: negCount - 1 }))}
        >
          Decrement
        </button>
        <p>{posCount}</p>
        <p>{negCount}</p>
      </div>
    );
  }
}

In the code above, we have the posCount and negCount states. Then we have 2 event handlers to set the state of posCount and negCount respectively. Then we display them in the p tags.

Since we destructured this.state in the render method’s first line, we can access them without referencing this.state in every line, saving us lots of typing and making the code a lot cleaner.

Conclusion

We can toggle components with a ternary expression if we want to toggle between 2 components. If we want to toggle one component on and off, we can use the && operator.

Also, we should destructure our props and states so that we don’t have to reference props , this.props or this.state all the time and make our code cleaner and we also can type less.

Categories
React Tips

React Tips — Modern Structures and State Updates

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps. In this article, we’ll look at some tips and tricks to make building apps with React easier.

Reduce the Use of Class Components

Class components have issues like dealing with lifecycle hooks and making sure the value of this is the correct one.

With the introduction of React hooks, function components are now smart. Therefore, we can use function components like we did we with class components, but without the headache of this and lifecycle hooks.

For instance, we can easily create a component that loads something from an API with the useEffect hook as follows:

import React from "react";

export default function App() {
  const [name, setName] = React.useState({});
  const getName = async () => {
    const res = await fetch("https://api.agify.io?name=michael");
    setName(await res.json());
  };
  React.useEffect(() => getName(), []);
  return <div className="App">{name.name}</div>;
}

In the code above, we have the React.useEffect call to call an API to get some data on load. We set the data with the setName function that’s returned from React.useState , which returns a state variable and a function to set the state.

Then we display it in the div that we returned.

To do the same thing with class-based components, we’ve to write the following:

import React from "react";

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {};
  }

  async componentDidMount() {
    const res = await fetch("https://api.agify.io?name=michael");
    this.setState({ name: await res.json() });
  }

  render() {
    return <div className="App">{this.state.name.name}</div>;
  }
}

As we can see, it’s a bit longer. Also, we have to extend the React.Component class to create a class component.

Also, we have to initialize this.state in the constructor and also call super .

In the componentDidMount hook, which is the same as using useEffect with an empty array as the second argument, we call the code to load the data that we want from the API.

Then we render the data in the render method with the div as we did before, except that we’ve to reference this.state to do that.

As we can see, the function component version is shorter. Also, we can use hooks however we see fit, unlike component lifecycle methods, which only run in certain parts of the lifecycle.

For instance, we can change the useEffect hook to watch for input value changes and call the API as follows:

import React from "react";

export default function App() {
  const [name, setName] = React.useState("");
  const [result, setResult] = React.useState({});
  const getName = async () => {
    const res = await fetch(`https://api.agify.io?name=${name}`);
    setResult(await res.json());
  };
  React.useEffect(() => {
    getName();
    return () => {};
  }, [name]);

  return (
    <div className="App">
      <input onChange={e => setName(e.target.value)} />
      <p>{result.name}</p>
    </div>
  );
}

In the code above, we used the useEffect hook to watch for the change of the value of name by passing name into the array of useEffect as the second argument.

The return statement in the useEffect callback is for running any cleanup code if needed.

We then call getName in a similar way as before, except that we interpolated name in the URL. As we can see, the useEffect hook does a lot more than a single lifecycle method in React can do. We did all that without having to reference this , which is also great since it’s always confusing.

This is one more reason to use function components with hooks.

Don’t use Props in Initial State

We shouldn’t use props in the initial state because the constructor is called only once when the component is created.

This means that when we make some changes to props next time, the component state won’t be updated.

The better way to reference props is to do it in componentDidUpdate . It’s a lifecycle method that lets us update the component when something change, such as when props change.

For instance, we can call this.setState in componentDidUpdate as follows:

import React from "react";

class Count extends React.Component {
  constructor() {
    super();
    this.state = {
      count: 0
    };
  }
  componentDidUpdate(prevProps) {
    if (this.props.count !== prevProps.count) {
      this.setState({ count: this.props.count * 2 });
    }
  }
  render() {
    return <div>{this.state.count}</div>;
  }
}

export default function App() {
  const [count, setCount] = React.useState(0);
  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <Count count={count} />
    </div>
  );
}

In the code above, we check if prevProps.count ‘s value is different from this.props.count ‘s the value before calling this.setState so that we don’t call it repeatedly and unstoppably. Then we render this.state.count that we set in the render method.

This is the right because we’re updating the state according to the value of the prop. We should get the count displaying the count prop passed in App multiplied by 2.

If it’s in the constructor, then this.state.count won’t update because it won’t update when the props change as we have in our example.

Conclusion

With the introduction of hooks, it’s time to embrace function components and hooks together to create stateful components. It reduces the headaches with dealing with lifecycle methods and the value of this .

Also, if we’re using class components, then we have to remember not to set props as the value of a state property in the constructor, because the prop will never update the state after the first time the component loads. Instead, we should call setState in componentDidUpdate to update the state with our prop value.