Categories
JavaScript Basics

Using Classes in JavaScript

Classes in JavaScript are a special syntax for its prototypical inheritance model that is a comparable inheritance in class-based object oriented languages. Classes are just special functions added to ES6 that are meant to mimic the class keyword from these other languages. In JavaScript, we can have class declarations and class expressions, because they are just functions. So like all other functions, there are function declarations and function expressions.

Classes serve as templates to create new objects.

The most important thing to remember: Classes are just normal JavaScript functions and could be completely replicated without using the class syntax. It is special syntactic sugar added in ES6 to make it easier to declare and inherit complex objects.

Defining Classes

To declare a class, we use the class keyword. For example, to declare a simple class, we can write:

class Person{
  constructor(firstName, lastName) {
    this.firstName= firstName;
    this.lastName = lastName;
  }
}

Class declarations aren’t hoisted so they can’t be used before they are defined in the code, as the JavaScript interpreter will not automatically pull them up to the top. So the class above won’t work before it’s defined in the code like the following:

const person = new Person('John', 'Smith');class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

We will get a ReferenceError if we run the code above.

We can also define a class by a class expression, which is an alternative syntax. They can be named or unnamed. We can also assign a class to a variable like we do with functions. If we do that, we can reference the class by its name. For example, we can define:

let Person = class {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

To get the name of the unnamed classes above, we can get the name with the name property, like so:

console.log(Person.name);

We can also define a named class like the following:

let Person = class Person2 {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

Then to get the name of the class, we can use the name property again. So we if we write:

console.log(Person.name)

We get Person2 logged.

The class body is defined with curly brackets. We define the class members inside the brackets. The body of the class is executed in strict mode, so everything defined in strict mode applies to the definition of a class, so we can’t define variables without keyword before it like var , let or const, and many other rules apply when you define a class.

Classes in JavaScript also have a constructor method that lets us set fields when the object is instantiated with a class. Each class can only have one constructor method in it. If there’s more than one, then SyntaxError will be thrown. A constructor can also call the super method to call the constructor of the super class if the class extends a parent class.

Methods that aren’t declared static constitutes the prototypical methods of the class. They are called after an object has been created by using the new keyword. For example, the following class has only prototypical methods:

class Person{
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  } get fullName(){
    return `${this.firstName} ${this.lastName}`
  } sayHi(){
    return `Hi, ${this.firstName} ${this.lastName}`
  }
}

In the Person class above, fullName and sayHi are prototypical methods. They are called like this:

const person = new Person('Jane', 'Smith');
person.fullName() // 'Jane Smith'

Static methods are methods that can be called without creating an object from the class using the new keyword. For instance, we can have something like the following:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  get fullName() {
    return `${this.firstName} ${this.lastName}`
  }
  sayHi() {
    return `Hi, ${this.firstName} ${this.lastName}`
  }
  static personCount() {
    return 3;
  }
}

We can call the personCount function without using the new keyword to create an instance of the class. So if we write:

Person.personCount

We get 3 returned.

The this value inside prototypical methods will be the value of the object. For static methods the value of this has the class that the static method is in as the value.

<img alt="Image for post" class="s t u dc ai" src="https://miro.medium.com/max/11426/0BvO6QcBmjOGtcHnL" width="5713" height="3809" srcSet="https://miro.medium.com/max/552/0BvO6QcBmjOGtcHnL 276w, https://miro.medium.com/max/1104/0BvO6QcBmjOGtcHnL 552w, https://miro.medium.com/max/1280/0BvO6QcBmjOGtcHnL 640w, https://miro.medium.com/max/1400/0*BvO6QcBmjOGtcHnL 700w" sizes="700px"/>

Photo by Thomas Kelley on Unsplash

Getters and Setters

JavaScript classes can have getter and setter functions. Getters, as the name suggests, is a method that lets us get some data from a class. Setters are methods that gives us the ability to set some fields of the class. We denote getter functions with the get keyword and setters with the set keyword. For example, we can write a class that has getters and setters like the following:

class Person {
  constructor(firstName, lastName) {
    this._firstName = firstName;
    this._lastName = lastName;
  }
  get fullName() {
    return `${this.firstName} ${this.lastName}`
  }
  get firstName() {
    return this._firstName
  }
  get lastName() {
    return this._lastName
  }
  sayHi() {
    return `Hi, ${this.firstName} ${this.lastName}`
  }
  set firstName(firstName) {
    this._firstName = firstName;
  }
  set lastName(lastName) {
    this._lastName = lastName;
  }
}

Then when we use the new keyword to construct a Person object, we can use them in the following way:

const person = new Person('Jane', 'Smith');
person.firstName = 'John';
person.lastName = 'Doe';
console.log(person.firstName, person.lastName)

Since we have the getter and setter functions, we can use them to set the data directly to set the data for firstName and lastName of the Person class. In the setter functions, which start with the keyword set, when we assign to a value them, it gest passed into the parameters and set in the member of the class. In the getter functions, which are denoted by get we return the member values which triggers the associated get function for the value.

JavaScript Inheritance

In JavaScript, we can create classes where the properties can be included in the properties of a child class.

So, we can have a high-level class that contains the properties that are common to all the child classes, and the child class can have its own special properties that are not in any other classes.

For example, if we have an Animal class with the common properties and methods, like name and the eat method, then the Bird class can just inherit the common properties in the Animal class. They don’t have to be defined in the Bird class again.

We can write the following to do inheritance in JavaScript:

class Animal {
  constructor(name) {
    this.name = name;
  }
  eat() {
    console.log('eat');
  }
}class Bird extends Animal {
  constructor(name, numWings) {
    super(name);
    this.numWings = numWings;
  }
}const bird = new Bird('Joe', 2);
console.log(bird.name)
bird.eat();

In the example above, we have the parent class, Animal, that has the eat method, which all classes that extends from Animal will have, so they don’t have to define eat again.

We have the Bird class which extends the Animal class. Note that in the constructor of the Bird class, we have the super() function call to call the parent’s class constructor to populate the properties of the parent class in addition to the properties of the child class.

Classes cannot extend regular objects, which cannot be constructed with the new keyword. If we want to inherit from a regular object, we have to use the Object.setPrototypeOf function to set a class to inherit from a regular object. For example:

const Animal = {
  eat() {
    console.log(`${this.name} eats`);
  }
};class Cat{
  constructor(name) {
    this.name = name;
  }
}class Chicken{
  constructor(name) {
    this.name = name;
  }
}Object.setPrototypeOf(Cat.prototype, Animal);
Object.setPrototypeOf(Chicken.prototype, Animal);let cat = new Cat('Bob');
let chicken = new Chicken('Joe');
cat.eat();
chicken.eat();

If we run the example code above, we can see Bob eats and Joe eats logged because we have inherited the eat function from the Animal object.

this Keyword

The this keyword allows us to access the current object’s properties inside the object, unless you’re using arrow functions.

As we can see from the above example, we can get the properties of the instance of the child and the parent class in the object.

Mixins

We can use mixins to do multiple inheritance in JavaScript. Mixins are templates for creating classes. We need mixins to do multiple inheritance because JavaScript classes can only inherit from one super class, so multiple inheritance isn’t possible.

For example, if we have a base class, we can define mixins to incorporate the members from multiple classes into one by composing the mixins by calling one and then pass the returned result into the next one as the argument, and so on, like the following:

class Base {
  baseFn() {
    console.log('baseFn called');
  }
}let classAMixin = Base => class extends Base {
  a() {
    console.log('classAMixin called');
  }
};let classBMixin = Base => class extends Base {
  b() {
    console.log('classBMixin called');
  }
};class Bar extends classAMixin(classBMixin(Base)) {}
const bar = new Bar();
bar.baseFn()
bar.a()
bar.b()

In the code above, we have the Base class which we pass into the classBMixin to get the b function into the Base class, then we call the classAMixin by passing in the result of classBMixin(Base) into the argument of the classAMixin to return the a function from classAMixin into the Base class and then return the whole class with all the functions from all the classes incorporated into one.

If we call all the functions above like we did by creating an instance of the Bar object and then call the baseFn, a, and b functions, we get:

baseFn called
classAMixin called
classBMixin called

This means that we have all the functions from the mixins incorporated into the new Bar class.

In JavaScript, classes are just syntactic sugar to make the prototypical inheritance of JavaScript clearer by letting us structure the code in a way that’s more like typical inheritance in class-based object oriented inheritance pattern. This means that we write classes to use the new keyword to create objects from the classes, but underneath the syntactic sugar, we are still using prototypical inheritance to extend objects. We can extend classes from objects and we can also use mixins to do multiple inheritance in JavaScript classes.

Categories
React Tips

React Tips — Testing, Redirects, and Markdown

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.

Pass Props with Redirect Component with React Router

We can pass props with React Router’s Redirect component by passing in the state value.

For instance, we can write:

<Redirect
  to={{
    pathname: '/order',
    state: { id: '123' }
  }}
/>

We pass in the pathname for the URL path.

And the state has the state we want to pass to the component.

And then we can write:

this.props.location.state.id

to get the id in the component.

Distinguish Left and Right Click Events with React

We can distinguish between left and right-click by checking the type property of the event object.

For instance, if we have:

return <p onClick={this.handleClick} onContextMenu={this.handleClick}>click me</p>

Then we can write:

handleClick(e) {
  if (e.type === 'click') {
    console.log('Left click');
  } else if (e.type === 'contextmenu') {
    console.log('Right click');
  }
}

This is detecting a synthetic event.

We can also detect left and right click with nativeEvent :

handleClick(e) {
  if (e.nativeEvent.which === 1) {
    console.log('Left click');
  } else if (e.nativeEvent.which === 3) {
    console.log('Right click');
  }
}

The which property has the click type.

1 is left click and 3 is for right-click.

Using Jest to Spy on Method Call in componentDidMount

We can use the spyOn method to check which component method is called.

for instance, we can write:

const spy = jest.spyOn(Component.prototype, 'someMethod');
const wrapper = mount(<Component {...props} />);
wrapper.instance().someMethod();
expect(spy).toHaveBeenCalled();

Component is the component we’re testing.

someMethod is the method we’re spying.

We mount the component and get the instance with the instance method.

someMethod is the method we called.

Then spy should be called.

And then we clear our spies with:

afterEach(() => {
  spy.mockClear()
})

after each test.

How to Capture Only Parent’s Click Event and not Children

We should call preventDefault to capture only the parent component’s click event and not the children’s.

For instance, we can write:

onParentClick(event) {
  event.preventDefault();
  console.log(event.currentTarget);
}

How to Render Markdown from a React Component

We can render markdown with the react-markdown library.

For instance, we can write:

import React from 'react'
import Markdown from 'react-markdown'

const code = "# header";

React.render(
  <Markdown source={code} />,
  document.getElementById('root')
);

We get the Markdown component form the package.

And then we pass in the code to the source prop to render it.

Also, we can convert it to HTML and then render than with dangerousSetInnerHTML with the marked library.

For instance, we can write:

import React from 'react';
import marked from 'marked';

class Markdown extends React.Component {
  constructor(props) {
    super(props);

    marked.setOptions({
      gfm: true,
      tables: true,
      breaks: false,
      pedantic: false,
      sanitize: true,
      smartLists: true,
      smartypants: false
    });
  }
  render() {
    const { text } = this.props,
    html = marked(text || '');

    return (
      <div>
        <div dangerouslySetInnerHTML={{__html: html}} />
      </div>
    );
  }
}

Markdown.propTypes = {
  text: React.PropTypes.string.isRequired
};

Markdown.defaultProps = {
  text: ''
};

We set the options with the setOptions method.

gfm means we render Github flavored Markdown.

tables means we render tables.

breaks mean we render line breaks with br.

pedantic means we conform to the original Markdown spec and don’t fix their bugs or behavior.

sanitize we sanitize the HTML.

smartLists uses the smartlist behavior of the Markdown spec.

smartypants means using smart typographic punctuation for things like quotes and slashes.

Testing with Jest Using Date Objects Produce Different Snapshots in Different Timezones

We can set the current time to be a constant time in Jest.

For instance, we can write:

Date.now = jest.fn(() => new Date(Date.UTC(2020, 7, 9, 8)).valueOf())

Then we can set the timezone when we run our tests.

In Mac and Linux, we add:

"test": "TZ=America/Los_Angeles react-scripts test --env=jsdom",

And in Windows, we add:

"test": "set TZ=America/Los_Angeles && react-scripts test --env=jsdom",

to package.json ‘s scripts section.

Conclusion

We can pass states to the Redirect component.

Also, we can set the time zone for the and date for Jest tests.

We can also spy on function calls with them.

We can also capture left and right clicks and clicks from parent elements only.

There are various ways to render Markdown in our React component.

Categories
React Tips

React Tips — Scroll to Top When Navigating

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.

Return Multiple Lines JSX in Another Return Statement in React

We can return multiple lines of JSX code in when we map them from an array by returning an array in the map callback.

For instance, we can write:

render() {
  return (
    {[1, 2, 3].map((n) => {
      return [
        <h3>Item {n}</h3>
        <p>{n}</p>
      ]
    }}
  );
}

We can also return a fragment to wrap around the components:

render() {
  return (
    {[1, 2, 3].map((n, index) => {
      return (
        <React.Fragment key={index}>
          <h3>Item {n}</h3>
          <p>{n}</p>
        </React.Fragment>
      )
    }}
  );
}

Get History on react-router

We can get the history with React Royer by calling the createBrowserHistory method.

For instance,e we can write:

import { Router } from 'react-router-dom'
import { createBrowserHistory } from 'history'
import App from './App'

const history = createBrowserHistory({
  //...
});

ReactDOM.render((
  <Router history={history}>
    <App />
  </Router>
), holder)

We can also use the withRouter higher-order component to inject the history object into a component.

For instance, we can write:

import { withRouter } from 'react-router-dom';

class App extends React.Component {
  render () {
    this.props.history;
  }
}

withRouter(App);

We called withRouter with App to inject the history prop to it.

Then in our App component, we can get the history with this.props.history .

Include a Font Awesome Icon in React’s render()

To include Font Awesome icons in our React app, we can install the package by running:

npm install --save font-awesome

Then we can include the bundled CSS by writing:

import '../node_modules/font-awesome/css/font-awesome.min.css';

or:

import 'font-awesome/css/font-awesome.min.css';

And then in our component, we write:

render() {
    return <div><i className="fa fa-spinner fa-spin"></i></div>;
}

We set the class names for the icon as the value of the className prop.

There’s also the react-fontawesome package that lets us use icons by including the them bundled React components in our components.

To install it, we run:

npm install --save react-fontawesome

Then we import it by adding:

const FontAwesome = require('react-fontawesome');

Then we can use it by writing:

class App extends React.Component {
  render() {
    return (
      <FontAwesome
        name='rocket'
        size='2x'
        spin
        style={{ textShadow: '0 1px 0 rgba(0, 0, 0, 0.1)' }}
      />
    );
  }
});

We use the FontAwesome component to add the icon.

React Router Scroll to Top on Every Transition

We can create our own component to scroll to the top and wrap that around the component that we want to scroll to the top.

For instance, we can write:

class ScrollToTop extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.location !== prevProps.location) {
      window.scrollTo(0, 0)
    }
  }

  render() {
    return this.props.children
  }
}

export default withRouter(ScrollToTop)

We call the withRouter prop with the ScrollToTop component.

Then we have the location prop available in ScrollToTop after that.

In the component, we check the location prop to see what the path is in the componentDidUpdate method.

If they’re different, that means we transitioned to a new route.

So we call window.scrollTo(0, 0) to scroll to the top of the page.

In render , we render the children prop so that we display the content of it.

Then, to use it, we write:

import ScrollToTop from './ScrollToTop';

//...

const App = () => (
  <Router>
    <ScrollToTop>
      <Foo />
    </ScrollToTop>
  </Router>
)

We wrap it our around Foo component to scroll it to the top when it’s loaded.

Also, we can do the same thing with hooks.

For instance, we can write:

import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';

function ScrollToTop({ history }) {
  useEffect(() => {
    const unlisten = history.listen(() => {
      window.scrollTo(0, 0);
    });
    return () => {
      unlisten();
    }
  }, []);

  return null;
}

export default withRouter(ScrollToTop);

We use withRouter again so that we get the history prop.

But we call history.listen instead of checking the value of history .

We call window.scrollTo(0, 0) whenever the callback of history.listen runs.

It returns a function to remove the listen.

So we put that into the function that’s returned in the useEffect callback.

We pass in an empty array as the 2nd argument of useEffect to only load the callback when the component mounts.

Then we use it by writing:

<Router>
  <>
    <ScrollToTop />
    <Switch>
        <Route path="/" exact component={Home} />
    </Switch>
  </>
</Router>

Conclusion

There are several ways to scroll to the top when we navigate to a different route.

We can return multiple components with map in an array.

Categories
React Tips

React Tips — Force Render, Conditionals, Listen for Navigation

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.

How to Force a Function Component to Render

We can force a function component to render with the use-force-update package.

To install it, we run:

npm install use-force-update

or:

yarn add use-force-update

Then we can use it by writing:

import useForceUpdate from 'use-force-update';

const App = () => {
  const forceUpdate = useForceUpdate();

  const rerender = () => {
    console('rerendering');
    forceUpdate();
  };

  return <button onClick={rerender} />;
};

We get the useForceUpdate hook to return the forceUpdate function that lets us update whenever we want.

Also, we can set a state to make a React component update.

For instance, we can write:

import React, { useState } from 'react';

function useForceUpdate(){
  const [value, setValue] = useState(0);
  return () => setValue(value => ++value);
}

function App() {
  const forceUpdate = useForceUpdate();

  return (
    <div>
      <button onClick={forceUpdate}>
        re-render
      </button>
    </div>
  );
}

We created our own useForceUpdate hook to update a value state.

The useState hook returns a state variable and a function to update it.

Whenever we update a state, React will render the component again.

componentDidMount Equivalent in a React Function Component

The equivalent of componentDidMount in a function component is the useEffect hook with an empty array.

For instance, we can write:

useEffect(() => {
  //...
}, []);

to make the code in the callback only load when the component mounts.

We can also pass in variables to the array to watch those values for changes:

useEffect(() => {
  //...
}, [foo, bar]);

The content can be any value like states, props, etc.

Detect Route Change with React Router

We can detect route change with React Router with the history.listen method.

For instance, we can write:

history.listen((location, action) => {
  console.log(location, action);
})

location is the native location object that has all the URL data like the pathname for the pathname.

search for the query string.

hash for the string after the hash.

action has the name for the navigation action.

Setting State on componentDidMount()

Setting state in the componentDidMount method isn’t an antipattern.

It’s a recommended practice for setting state when the component mounts.

For instance, we can use it to get API data and set the state:

componentDidMount() {
  fetch("https://randomuser.me/api")
    .then(res => res.json())
    .then(
      (result) => {
        this.setState({
          isLoaded: true,
          user: results[0]
        });
      },
      (error) => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    )
}

We get the data from an API with the fetch API.

Then we get the resulting data in the first then callback to set the state for the data.

In the 2nd callback, we set the isLoaded state to false and an error state.

Use if…else… Statement in React render Function

There are a few ways to display things conditionally with React.

We can use various boolean expressions to do so.

For example, we can write:

render() {
  const { isLoggedIn } = this.state;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleClick} />
      ) : (
        <LoginButton onClick={this.handleClick} />
      )}
    </div>
  );
}

We get the isLoggedIn state and use that to check the if the user is logged in.

If the user isn’t then we return LogoutButton .

Otherwise, we return LoginButton .

We can also use an if-else statement to assign a component to a variable/

For instance, we can write:

render() {
  let button;
  if (isLoggedIn) {
    button = <LogoutButton onClick={this.handleClick} />;
  } else {
    button = <LoginButton onClick={this.handleClick} />;
  }

  return (
    <div>
      {button}
    </div>
  );
}

We check isLoggedIn with an if-else statement instead of a ternary expression.

We assigned our components to the button variable and render that instead of writing everything inline.

This lets us write longer expressions in a conditional statement.

Also, we can use the && operator to display things given a condition.

For example, we can write:

render() {
  return (
    <div>
      {cartItems.length > 0 &&
        <h2>
          You have {cartItems.length} in the cart.
        </h2>
      }
    </div>
  );
}

If cartItems.length > 0 is true then the stuff that comes after it is rendered.

Conclusion

We can force a component to render in various ways.

Also, we can display things conditionally with several kinds of statements and expressions.

And we can use history.listen to listen for changes in React Router.

Categories
React Tips

React Tips — Redirect, Error Handling and Redux, and .env Files

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.

React Button Redirect Page on Click

We can redirect to a page when we click on an element by getting the history object.

For instance, we can write:

import React from 'react';
import { useHistory } from "react-router-dom";
function LoginPage () {
  const history = useHistory();
  const onClick = () => {
    history.push('new-page');
  }

  return (
    <div>
      <button
        onClick={onClick}
      >
        Login
      </button>
    </div>
  );
}
export default LoginPage;

We get the native history object with useHistory

Then we define the onClick function to call history.push to navigate to a new page.

If we’re using class components, we can write:

import { withRouter } from 'react-router-dom';

class LoginPage extends Component {
  constuctor() {
    this.routeChange = this.routeChange.bind(this);
  }

  onClick() {
    this.props.history.push('forgot-password');
  }

  render() {
    return (
      <div>
        <button onClick={onClick}>Forgot password?</button>
      </div>
    );
  }
}

export default withRouter(LoginPage);

We have the LoginPage class component.

To make the history prop available to the component, we pass it to withRouter .

We have the onClick method that calls the this.props.history.push method to navigate to the new page.

The routerChange method has to be bound to the component with bind so that we set the component class as the value of this .

Render Boolean Value in JSX

We can render boolean value in JSX by converting it to a string first.

For instance, we can write:

Boolean Value: {bool.toString()}

or:

Boolean Value: {String(bool)}

or:

Boolean Value: {'' + bool}

or:

{`Boolean Value: ${bool}`}

or:

Boolean Value: {JSON.stringify(bool)}

There are many ways to convert a boolean value into a string.

They’re all good except for the concatenation, which may be confusing.

Using event.target with React Components

We can use event.target to get a DOM element’s properties.

We can use the dataset property to get attributes prefixed with the data- prefix.

They’re considered custom attributes that let us pass data around with an element.

For instance, if we have a button, then we can write:

<button
  data-foo="home"
  data-bar="home"
  onClick={this.props.onClick}
/>
  Button
</button>

Then we can write:

onClick(e) {
   console.log(e.target.dataset.bar, e.target.dataset.foo);
}

to get the foo and bar properties from the button that we clicked with the dataset property.

dataset.foo has the value of the data-foo attribute.

dataset.bar has the value of the data-bar attribute.

Adding a .env File to React Project

If we have a create-react-app project, we can add an .env file to add the environment variables.

Inside the file, any keys that are prefixed with the REACT_APP_ prefix are read into the app.

So in our .env file, we can write:

REACT_APP_API_KEY=secret

We can then use the environment variable values by writing:

fetchData() {
  fetch(`https://example.com?api-key=${process.env.REACT_APP_API_KEY}`)
    .then((res) => res.json())
    .then((data) => console.log(data))
}

We read the environment variable value with the process.env object.

How to Pass Multiple Parameters to Input’s onChange Handler

We can pass in multiple parameters to an input’s onChange handler.

To do that, we can write:

<Input
  type="text"
  value={this.state.name}
  onChange={this.onChange.bind(this, this.state.user.id)}
/>

Then we can define our onChange method by writing:

onChange(`userId`, event) {
  const newName = event.target.value;
},

We have whatever we pass in as the first argument.

And the last argument is the object.

How to Catch and Handle Error Response 422 with Redux and Axios

We can call dispatch to dispatch the action within a React component.

For instance, we can write:

axios({
  method: 'post',
  responseType: 'json',
  url: `${SERVER_URL}/login`,
  data: {
    username,
    password
  }
})
 .then(response => {
   dispatch(setUser(response));
 })
 .catch(error => {
   dispatch({ type: AUTH_FAILED });
   dispatch({ type: ERROR, payload: error.data.error.message });
 });

We make a POST request with Axios.

Then in the then callback, we get the response and call dispatch and our setUser action creator.

And then we call the catch method with a callback to handle errors.

We call dispatch with or without a payload.

Calling dispatch would update the store with the new state value.

Conclusion

We can redirect pages on click.

And we can handle errors with Redux by calling dispatch to update the stores.

Booleans can be rendered if we convert them to a string.