Categories
React Answers

How to fix Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks?

To fix Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement in React Hooks, we should put hook calls at the top level of a component.

For instance, we write

const { useState } = React;

function App() {
  const [name, setName] = useState("Mary");
  const [age, setAge] = useState(16);
  const [license, setLicense] = useState("A123456");

  return (
    <div>
      Name:{" "}
      <input
        value={name}
        onChange={(e) => {
          setName(e.target.value);
        }}
      />
      <br />
      Age:{" "}
      <input
        value={age}
        type="number"
        onChange={(e) => {
          setAge(+e.target.value);
        }}
      />
      {age >= 16 && (
        <span>
          <br />
          Driver License:
          <input
            value={license}
            onChange={(e) => {
              setLicense(e.target.value);
            }}
          />
        </span>
      )}
    </div>
  );
}

to call useState at the top of the App component only.

Then React can call all the hooks in order.

We should not nest any hooks in our component.

Otherwise, we’ll get this error.

Categories
React Answers

How to fix React form setState is one step behind onChange?

Sometimes, we want to fix React form setState is one step behind onChange

In this article, we’ll look at how to fix React form setState is one step behind onChange.

How to fix React form setState is one step behind onChange?

To fix React form setState is one step behind onChange, we call setState with an object with the states we want to change and a function that’s called after the states are changed.

For instance, we write

class Comp extends Component {
  //...
  handleChange = (e) => {
    console.log(e.target.value);
    this.setState({ message: e.target.value }, this.handleSubmit);
  };
  //...
}

to call setState with { message: e.target.value } to set the message state to e.target.value.

After the states are set then this.handleSubmit is called.

Conclusion

To fix React form setState is one step behind onChange, we call setState with an object with the states we want to change and a function that’s called after the states are changed.

Categories
React Answers

How to make API call with hooks in React?

Sometimes, we want to make API call with hooks in React.

In this article, we’ll look at how to make API call with hooks in React.

How to make API call with hooks in React?

To make API call with hooks in React, we can do it in the useEffect callback.

For instance, we write

const Todo = () => {
  const [todo, setTodo] = React.useState(null);
  const [id, setId] = React.useState(1);

  const getTodo = async (id) => {
    const results = await fetch(
      `https://jsonplaceholder.typicode.com/todos/${id}`
    );
    const data = await results.json();
    setTodo(data);
  };

  React.useEffect(() => {
    if (id === null || id === "") {
      return;
    }
    getTodo(id);
  }, [id]);

  return (
    <div>
      <input value={id} onChange={(e) => setId(e.target.value)} />
      <br />
      <pre>{JSON.stringify(todo, null, 2)}</pre>
    </div>
  );
};

to define the getTodo which makes a get request to an endpoint to get some data.

We get the response data from the json method.

Then we call useEffect with a callback that calls getTodo with id.

The 2nd argument is [id] so the useEffect callback will be called when id changes.

Conclusion

To make API call with hooks in React, we can do it in the useEffect callback.

Categories
React Answers

How to detect when user scrolls to bottom of div with React?

Sometimes, we want to detect when user scrolls to bottom of div with React.

In this article, we’ll look at how to detect when user scrolls to bottom of div with React.

How to detect when user scrolls to bottom of div with React?

To detect when user scrolls to bottom of div with React, we check if the sum of the scrollTop and clientHeight of the scroll container is the same as its scrollHeight.

For instance, we write

import React, { useRef, useEffect } from "react";

const MyListComponent = () => {
  const listInnerRef = useRef();

  const onScroll = () => {
    if (listInnerRef.current) {
      const { scrollTop, scrollHeight, clientHeight } = listInnerRef.current;
      if (scrollTop + clientHeight === scrollHeight) {
        // ...
        console.log("Reached bottom");
      }
    }
  };

  return (
    <div className="list">
      <div className="list-inner" onScroll={onScroll} ref={listInnerRef}>
        {/* List items */}
      </div>
    </div>
  );
};

to call onScroll when we scroll by setting the onScroll prop of the div to onScroll.

Then we assign a listInnerRef to the div.

In onScroll, we check if the sum of the scrollTop and clientHeight of the scroll container is the same as its scrollHeight.

If it is, then the bottom of the element is reached.

Conclusion

To detect when user scrolls to bottom of div with React, we check if the sum of the scrollTop and clientHeight of the scroll container is the same as its scrollHeight.

Categories
React Answers

How to prevent multiple times button press with React?

Sometimes, we want to prevent multiple times button press with React.

In this article, we’ll look at how to prevent multiple times button press with React.

How to prevent multiple times button press with React?

To prevent multiple times button press with React, we can set the disabled prop of the button.

For instance, we write

import React, { useState } from "react";

const Button = () => {
  const [double, setDouble] = useState(false);
  return (
    <button
      disabled={double}
      onClick={() => {
        // ...
        setDouble(true);
      }}
    />
  );
};

export default Button;

to set disabled to the double state.

And we call setDouble with true to set double to true after the first click.

Conclusion

To prevent multiple times button press with React, we can set the disabled prop of the button.