Categories
React Answers

How to validate input values with React?

To validate input values with React, we can use react-hook-form.

To install it, we run

npm i react-hook-form

Then we use it by writing

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

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} />

      <input name="lastname" ref={register({ required: true })} />
      {errors.lastname && "Last name is required."}

      <input name="age" ref={register({ pattern: /\d+/ })} />
      {errors.age && "Please enter number for age."}

      <input type="submit" />
    </form>
  );
}

to call the useForm hook to return an object with a few properties we use.

Then we add a form element with the onSubmit prop set top handleSubmit(onSubmit).

We use handleSubmit to return a function that does form validation before calling onSubmit.

We call register to register form fields and add validation rules.

And we should errors using the errors property.

Categories
React Answers

How to fix div cannot appear as a descendant of p error with React?

To fix div cannot appear as a descendant of p error with React, we should make sure we don’t have divs that are inside p elements.

For instance, we shouldn’t write

<p>
  <div>...</div>
</p>

in our React components.

If we’re using the Material UI Typography component, we can change the component prop so that we don’t render a div inside a p element.

To do this, we write

<Typography component={"span"} variant={"body2"}>
  ...
</Typography>

to set the component prop to 'span' so that Typography doesn’t render a div inside a p element.

Categories
React Answers

How to get something from the state or store inside a React Redux-Saga function?

To get something from the state or store inside a React Redux-Saga function, we call the select function.

For instance, we write

export const getProject = (state) => state.project;

// Saga
export function* saveProjectTask() {
  while (true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject);
    yield call(fetch, "/api/project", { body: project, method: "PUT" });
    yield put({ type: SAVE_PROJECT_SUCCESS });
  }
}

to call select with the getProject to get the project state from the store.

Categories
React Answers

How to respond to the width of an auto-sized DOM element in React?

To respond to the width of an auto-sized DOM element in React,m we can use the react-measure hook.

To install it, we run

npm i react-measure

Then we use it by writing

import * as React from "react";
import Measure from "react-measure";

const MeasuredComp = () => (
  <Measure bounds>
    {({
      measureRef,
      contentRect: {
        bounds: { width },
      },
    }) => <div ref={measureRef}>My width is {width}</div>}
  </Measure>
);

to use the Measure component from react-measure to retuen the width of the div by assigning the measureRef provided as the value of the div’s ref prop.

Categories
React Answers

How to style components using makeStyles and still have lifecycle methods in React Material UI?

To style components using makeStyles and still have lifecycle methods in React Material UI, we call makeStyles outside our component.

And then we use the useStyles hook returned from makeStyles to apply the styles.

For instance, we write

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Redirect } from "react-router-dom";

import { Container, makeStyles } from "@material-ui/core";

import LogoButtonCard from "../molecules/Cards/LogoButtonCard";

const useStyles = makeStyles((theme) => ({
  root: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    margin: theme.spacing(1),
  },
  highlight: {
    backgroundColor: "red",
  },
}));

const Welcome = ({ highlight }) => {
  const [userName, setUserName] = useState("");
  const [isAuthenticated, setIsAuthenticated] = useState(true);
  const classes = useStyles();

  //...
  if (!isAuthenticated()) {
    return <Redirect to="/" />;
  }
  return (
    <Container
      maxWidth={false}
      className={highlight ? classes.highlight : classes.root}
    >
      <LogoButtonCard
        buttonText="Enter"
        headerText={isAuthenticated && `Welcome, ${userName}`}
        buttonAction={login}
      />
    </Container>
  );
};

export default Welcome;

to call makeStyles with an object with the class names set to objects with the styles for each class name.

Then we call useStyles in Welcome to return the classes object.

And then we apply the styles to Container from the classes object in the className prop.