Categories
React Tips

React Tips — Pseudo-Elements, Conditional Display and Constructor

React is a popular library for creating web apps and mobile apps.

In this article, we’ll look at some tips for writing better React apps.

Conditionally Displaying Items in a React Component

We can conditionally display items in a React component in various ways.

One way is to use a ternary expression.

For instance, we can write:

render() {
  return (
    this.props.showMe ? <button type="submit">show me</button> : null
  );
}

The first item is shown if showMe is true and null is rendered otherwise.

We can also use the && operator.

For instance, we can write;

`{`showMe `&&` <button type="submit">show me</button>`}`

Is showMe is true then the button is rendered since the expression will be evaluated.

CSS Pseudo-elements in React

We can add prefixed styled by adding them as properties of the style object.

For instance, we can write:

render() {
  return (
    <div>
      <span>Something</span>
      <div style={{ WebkitFilter: 'blur(10px) saturate(2)' }} />
      </div>
  );
},

We have the WebkitFilter property which is equivalent to CSS’s -webkite-filter property.

To make our lives raise,r we can use the style-it package to convert any CSS property to JavaScript style properties.

To install it, we run:

npm install style-it --save

Then we can use it by writing:

import React from "react";
import Style from "style-it";
class Intro extends React.Component {
  render() {
    return Style.it(
      `
        .tooltip {
          display:inline-block;
          position:relative;
          border-bottom:1px dotted #666;
          text-align:left;
        }
        .tooltip .right {
          min-width:200px;
          top:50%;
          left:100%;
          margin-left:20px;
          transform:translate(0, -50%);
          padding:10px 20px;
          color:#444444;
          background-color:#EEEEEE;
          font-weight:normal;
          font-size:13px;
          border-radius:8px;
          position:absolute;
          z-index:99999999;
          box-sizing:border-box;
          box-shadow:0 1px 8px rgba(0,0,0,0.5);
          display:none;
        }
        .tooltip:hover .right {
          display:block;
        }
        .tooltip .right i {
          position:absolute;
          top:50%;
          right:100%;
          margin-top:-12px;
          width:12px;
          height:24px;
          overflow:hidden;
        }
        .tooltip .right i::after {
          content:'';
          position:absolute;
          width:12px;
          height:12px;
          left:0;
          top:50%;
          transform:translate(50%,-50%) rotate(-45deg);
          background-color:#EEEEEE;
          box-shadow:0 1px 8px rgba(0,0,0,0.5);
        }
    `,
      <div id="tooltip" />
    );
  }
}

We use the Style component with the CSS embedded in the string.

Then anything that comes after the string will be styled with the given styles.

Also, we can use the styled-components library to do the same thing.

We can install it by running:

npm i styled-components

Then we can write:

import React from 'react';
import styled from 'styled-components';

const Tooltip = styled.div`
  .tooltip {
    display:inline-block;
    position:relative;
    border-bottom:1px dotted #666;
    text-align:left;
  }
  .tooltip .right {
    min-width:200px;
    top:50%;
    left:100%;
    margin-left:20px;
    transform:translate(0, -50%);
    padding:10px 20px;
    color:#444444;
    background-color:#EEEEEE;
    font-weight:normal;
    font-size:13px;
    border-radius:8px;
    position:absolute;
    z-index:99999999;
    box-sizing:border-box;
    box-shadow:0 1px 8px rgba(0,0,0,0.5);
    display:none;
  }
  .tooltip:hover .right {
    display:block;
  }
  .tooltip .right i {
    position:absolute;
    top:50%;
    right:100%;
    margin-top:-12px;
    width:12px;
    height:24px;
    overflow:hidden;
  }
  .tooltip .right i::after {
    content:'';
    position:absolute;
    width:12px;
    height:12px;
    left:0;
    top:50%;
    transform:translate(50%,-50%) rotate(-45deg);
    background-color:#EEEEEE;
    box-shadow:0 1px 8px rgba(0,0,0,0.5);
  }
}
`;

const App = () => {
  return (
    <Tooltip>...</Tooltip>
  )
}

We used the styled.div template tag, which is a function that takes CSS styles and returns a component with the styles.

Then we can use them in our component as we did in App .

Functions in Stateless Components

We can call functions that are outside of the component within the component.

For instance, we can write:

const App = props => (
  <Something onClick={props.update} />
);

We can get functions from props and call them.

We can also have functions inside the component.

For instance, we can write:

const App  = props => {
  const onClick = useCallback((a, b) => {
    //...
  }, [props.x]);

  return (
    <Something onClick={onClick} />
  );
}

We use the useCallback gook to ensure that functions are only redefined when one of the dependencies in the array changes.

Calling super() in a React Component Constructor

We call super inside the constructor if we have to use this.props .

For instance, we writ:

class App extends React.component{
  constructor(props){
    super(props);
    console.log(this.props);
  }
}

So that we get access to this.props in our component’s code.

Subclasses must call super before referencing this either simplicity or explicitly.

Conclusion

We can use libraries to incorporate pseudo-classes in our React component code.

Also, we’ve to call super before using this in class components.

Items can be conditionally displayed with boolean expressions.

Categories
React Tips

React Tips — Basic Hooks

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 some basic hooks that are built-into React to make our function components smart.

State and useState

We can use the useState hook to store the state of our app. Therefore, it’s a basic building block of a smart React function component.

To use it, we write the following code:

import React from "react";

export default function App() {
  const [count, setCount] = React.useState(0);

  return (
    <>
      <button onClick={() => setCount(count => count - 1)}>decrement</button>
      <p>{count}</p>
    </>
  );
}

In the code above, we have the count state returned as the first element of the array returned by the useState hook.

We then defined an onClick handler which calls the setCount function returned as the 2nd element in the array returned by useState .

In there, we updated the count by returning the existing count value minus 1.

This lets us modify a state’s value based on its previous value. We can also pass in whatever we want to set directly if it doesn’t depend on the previous value of a state.

Passing in a callback will guarantee that the update is done based on the previous value of the state.

For instance, we can pass in a value directly into the state change function as follows:

import React from "react";

export default function App() {
  const [text, setText] = React.useState("foo");

  return (
    <>
      <button onClick={() => setText("foo")}>foo</button>
      <button onClick={() => setText("bar")}>bar</button>
      <button onClick={() => setText("baz")}>baz</button>
      <p>{text}</p>
    </>
  );
}

In the code above, we have 3 buttons that have click handlers that call setText to set the value of the text state.

Since the value we set doesn’t depend on the previous value, we can just set it directly by passing in the value that we want to set the value of text to.

The state change function can be used more than once, as we can see from the previous example.

It can accept any kind of value, including primitive values and objects.

Side effects and useEffect

The React useEffect hook is another important hook that we can’t overlook.

It’s used to commit side effects like updating data asynchronously from an API or working with the DOM.

Side effects are actions that can change our component in an unpredictable fashion.

It accepts a callback function that is run during every render. To restrict the callback to run only when a specified value is changed, we pass in a second argument with an array of the value that we want to watch and run the callback when they change.

If we pass in an empty array as the 2nd argument, then the callback only runs when during the first render.

For instance, we can use it as follows:

import React, { useEffect } from "react";

export default function App() {
  const [name, setName] = React.useState("");
  const [data, setData] = React.useState({});

  const getData = async () => {
    const res = await fetch(`https://api.agify.io/?name=${name}`);
    const d = await res.json();
    setData(d);
  };

  useEffect(() => {
    getData();
  }, [name]);

  return (
    <>
      <input value={name} onChange={e => setName(e.target.value)} />
      <p>
        {data.name} {data.age}
      </p>
    </>
  );
}

In the code above, we have an input that changes the value of the name state as we type something in it.

Then with the useEffect hook, we watch for changes in name so that getData is called when the name value changes.

In the getData function, we call setData to set the data and display the data that’s obtained from the API call.

We should just pass in an array as the 2nd argument always so that the callback won’t run during every render accidentally.

If we need to do clean up, we should return a function inside the useEffect callback and run any cleanup code inside the callback if needed.

We can use add clean up code as follows:

import React, { useEffect } from "react";

export default function App() {
  const [mousePosition, setMousePosition] = React.useState({});
  const { x, y } = mousePosition;

  const handleMouseMove = event => {
    const { pageX, pageY } = event;
    setMousePosition({
      x: pageX,
      y: pageY
    });
  };

  useEffect(() => {
    window.addEventListener("mousemove", handleMouseMove);

    return () => window.removeEventListener("mousemove", handleMouseMove);
  });

  return (
    <>
      <p>
        ({x}, {y})
      </p>
    </>
  );
}

In the code above, we added an event handler for the mousemove event called handleMousemove , which takes the mouse position and calls setMousePosition to set the mousePosition state.

We then watch the mouse position by writing:

window.addEventListener("mousemove", handleMouseMove);

in the useEffect callback. Below it, we have:

return () => window.removeEventListener("mousemove", handleMouseMove);

to remove the mousemove event listener when the App component is no longer being rendered.

Conclusion

The useState and useEffect hook are the 2 most useful and basic hooks in the React standard library.

They let us update state and commit side effects respectively.

Categories
React Tips

React Tips — Fragments, Lists, and Events

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 how to render a group of elements and components without a wrapper element with fragments, render lists in React apps, and handle events.

Fragments

In React, fragments are React components that don’t render anything in the DOM. We can use fragments to group components together that are rendered together.

For instance, we can write the following code to use them in our code:

import React from "react";

export default function App() {
  return (
    <>
      <h1>foo</h1>
      <h2>bar</h2>
    </>
  );
}

In the code above, the empty tags are the opening and closing tags for fragments. We used it to wrap around the h1 and h2 elements.

When we inspect the DOM in the browser developer console, we don’t see anything in the DOM that corresponds to the fragment.

We can also write out the long form of the fragment as follows:

import React from "react";

export default function App() {
  return (
    <React.Fragment>
      <h1>foo</h1>
      <h2>bar</h2>
    </React.Fragment>
  );
}

It’s the same thing, but we can pass props to it if necessary. We can’t pass props with the shorthand version.

Fragments are good for grouping anything.

Lists and Keys

We can use the array’s map method to convert array data to React components.

For instance, we can use the map method as follows to map array entries to components we display on the screen as follows:

import React from "react";

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

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

In the code above, we have the names array, which we mapped into a list of p elements using the map method. In the callback, we return the p element with the key prop set to a unique value. In this case, we set key ‘s value to the array index, which is unique.

It’s also good for mapping data to elements, as we do in the following code:

import React from "react";

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

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

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

In the code above, we created the Names component, which renders the p element that we have before.

We used map the same way but set the key prop of the Name component instead.

We need to set the key prop to a unique value for each entry so that React can keep track of the element that’s being iterated over with map .

If we skip the keys, then it’s harder to React to figure out how each element should be updated when they change.

Events and Event Handlers

React and HTML event handler is different. The case is different. For instance, in HTML, we create a click handler and attach it to an element by writing the following code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>App</title>
    <script>
      const onClick = () => {
        alert("hello");
      };
    </script>
  </head>
  <body>
    <button onclick="onClick()">
      foo
    </button>
  </body>
</html>

In the code above, we have the onClick function, which is run when the click event is triggered on the button since we have:

onclick="onClick()"

on our button.

With React, we have something similar. However, the case is different and React events aren’t the same as regular HTML events. They only work on React’s Virtual DOM. The Virtual DOM is React’s representation of the real DOM on our page.

In React apps, we write something like the following to attach a click handler to a button:

import React from "react";

export default function App() {
  const onClick = () => alert("hello");

  return (
    <>
      <button onClick={onClick}>foo</button>
    </>
  );
}

In the code above, we have the onClick function, which is run when the click event on the button in the React’s Virtual DOM is triggered.

Also, we passed in reference to the onClick function rather than running it inside the attribute as we saw in the HTML example. We never run the function inside props, we always pass in the value. Otherwise, React will re-render the component infinite times.

Conclusion

Fragments let us group elements and components together without having to render a wrapper element.

Lists can be created by calling map on an array.

Events handled in React apps by attaching events to React elements. The handler function reference is passed into the appropriate prop to run the function when the event is triggered.

Categories
React Tips

React Tips — Form Validation

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 do form validation in React apps.

Form Validation and React

Form validation isn’t included in React since it’s just a view library. We’ve to deal with watching form values and form validation ourselves. To make the job easy, we can use a library to do it.

React Hook Form

One easy library that we can use to do form validation is the React Hook Form library.

We can get started by running the following to install it:

npm install react-hook-form

Once we install it, we can use it as follows:

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => {
    console.log(data);
  };

  console.log(watch("name"));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="name"
        defaultValue="foo"
        ref={register({ required: true })}
      />
      {errors.name && <span>This field is required</span>}
      <input name="age" ref={register} />
      <input type="submit" />
    </form>
  );
}

In the code above, we used the react-hook-form library to create a form first by using the useForm hook that’s built into react-hook-form to return a few objects that we need to create a form with validation.

Then we create a form with validation by passing in the handleSubmit function into the onSubmit function, which is our submit handler, as the argument.

Then we set the name of the input, which is used for form validation. In the ref prop, we pass in the register function, with the required property set as an optional property to indicate that it’s a required field.

The defaultValue prop lets us set the default value of an input.

If it’s not a field that needs validation, then we just pass in the reference of the register function that’s returned from the useForm hook.

To display error messages, we can get the errors.name variable to get any errors from a field with the given name. In this case, errors.name get the errors from the field with the name attribute set to name .

Then if that’s true , we display an error message.

We can also watch values with the watch function as we have above.

Notice that it doesn’t have any form value handling code. It’s all done by react-hook-form , which is good since it’s less typing for us.

In the end, when we type in something into the input, we’ll see it displayed in the box. When we don’t have anything in the required name input and click Submit, we’ll get an error.

Validation Rules

We can easily change the basic form we have above to include validation rules like number range.

For instance, we can add a number range validation into the age input in the example above as follows:

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => {
    console.log(data);
  };

  console.log(watch("name"));

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="name"
        defaultValue="foo"
        ref={register({ required: true })}
      />
      {errors.name && <span>This field is required</span>}
      <input
        name="age"
        type="number"
        ref={register({ required: true, min: 0, max: 200 })}
      />
      {errors.age && <span>Age must be between 0 and 200</span>}
      <input type="submit" />
    </form>
  );
}

In the code above, we changed the age input to:

<input
  name="age"
  type="number"
  ref={register({ required: true, min: 0, max: 200 })}
/>

We added the min and max validators and set the input type to number. This way, we get validation of numeric ranges.

Then we added an error display below it which displays when error.age is true .

Conclusion

We can do basic form validation with the react-hook-form package. It lets us easily create forms by using the useForm hook and passing in a few props.

It also handles data binding and form submission without writing our own code to do it.

The package comes with its own validation rules, which can be applied flexibly. We can also watch the values of each field as it changes.

Categories
React Tips

React Tips — Stateless Components and Spreading Props

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 use stateless components to simplify our code and spreading props so we don’t have to pass them explicitly.

Stateless Components

Stateless components are components that don’t hold state. We can define stateless components with function and class components.

They only take props and render them.

They’re easy to test since we don’t have to mock and change states in order to test them.

We can define the class component that is stateless as follows:

import React from "react";

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

In the code above, we have the render method that render firstName , lastName , and age from the props by destructuring this.props .

Then when we add the following below Person:

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

We’ll see Jane Smith 20 displayed on the screen.

We can make stateless components a lot simpler with function components. For instance, we can rewrite Person as a function component as follows:

import React from "react";

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

In the code above, we have a React function component. The first parameter has our props. We destructured the prop’s properties into individual variables.

Then we return them in immediately in the p element.

This is a lot simpler and we also saved a lot of typing by eliminating lots of boilerplate code that class-based components need to have.

Spreading Props as we Pass Them

To make passing lots of props cleaner, we can use the spread operator to spread them so that we don’t have to pass props by writing them all out explicitly.

For instance, we can write the following code to do that:

import React from "react";

const person = {
  firstName: "Jane",
  lastName: "Smith",
  age: 20
};

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

export default function App() {
  return (
    <>
      <div>
        <Person {...person} />
      </div>
    </>
  );
}

In the code above, we have the person object. We want to pass in the properties of person as props. In the code above, we passed in the firstName , lastName and age prop by spreading the person object as follows:

<Person {...person} />

Then the Person prop, will pick up the values of firstName , lastName , and age and render them in the p element of Person .

This is much cleaner than writing them out one by one as follows:

import React from "react";

const person = {
  firstName: "Jane",
  lastName: "Smith",
  age: 20
};

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

export default function App() {
  return (
    <>
      <div>
        <Person
          firstName={person.firstName}
          lastName={person.lastName}
          age={person.age}
        />
      </div>
    </>
  );
}

As we can see:

<Person
  firstName={person.firstName}
  lastName={person.lastName}
  age={person.age}
/>

is a lot longer than:

<Person {...person} />

In the shorter version, we didn’t have to reference person and the prop names in every line. It’s way shorter and saved us lots of typing, and they do the same thing.

Deduplicate Our Components

If we have code that’s very similar to each other, we should find a way to deduplicate them. For instance, the following code has lots of duplicate code:

import React from "react";

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

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

In the code above, we have:

<Person firstName="John" lastName="Smith" age={20} />
<Person firstName="Jane" lastName="Smith" age={20} />

which is mostly overlapping code except for the value of the firstName prop.

We can clean that up by creating another component that has shared parts in one place. For example, we can write the following code to do that:

import React from "react";

const common = {
  firstName: "Jane",
  lastName: "Smith",
  age: 20
};

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

const FamilyMember = ({ firstName }) => {
  return <Person {...common} firstName={firstName} />;
};

export default function App() {
  return (
    <>
      <div>
        <FamilyMember firstName="John" />
        <FamilyMember firstName="Jane" />
      </div>
    </>
  );
}

In the code above, we have the FamilyMember component, which has the common object’s properties set as props to eliminate the duplicate prop values, then we reference FamilyMember in App , which only has common props in one place.

Then we get:

John Smith 20

Jane Smith 20

displayed on the screen. Putting the code in one makes changing it easier even though it may not be the shortest way in this case.

Conclusion

We should use stateless components wherever we can to reduce the burden of testing. They’re also simpler.

Also, we can spread props into components so that we don’t have to write them all out.

Finally, if we have components with lots of common props, we should eliminate the duplicates by putting them all in one component.