Categories
React

How to Programmatically Clear or Reset a React-Select Dropdown?

We can programmatically clear a React-Select dropdown by resetting the value that is set as the value of the value prop to null .

Then the dropdown will be cleared.

For instance, we can write:

import { useState } from "react";
import Select from "react-select";

const options = [
  { value: "one", label: "One" },
  { value: "two", label: "Two" }
];

export default function App() {
  const [value, setValue] = useState("one");

  const handleChange = (value) => {
    setValue(value);
  };

  return (
    <div className="App">
      <Select
        name="form-field-name"
        value={value}
        onChange={handleChange}
        options={options}
      />
      <button onClick={() => setValue(null)}>reset</button>
    </div>
  );
}

We have the options array with the value and label properties.

value has the selection’s value.

label is the value displayed to the user.

The value state is set as the value of the value prop.

Then we have the handleChange function that takes the value parameter and call setValue to change the value of value .

We set the onChange prop to the handleChange function so that we can set the value of value .

The options prop is set to the options array.

We have a button to call setValue with null to clear the dropdown value.

Categories
React

Where Can We Make API Calls with Hooks in React?

Making HTTP requests is something that we have to do often in our React code.

In this article, we’ll look at where we should make API calls in React components that are made with React hooks.

API Call on Mount Only

To make an API call when the component mounts only, we can use the useEffect callback with an empty array as the 2nd argument.

For instance, we can write:

import { useEffect, useState } from "react";

export default function App() {
  const [user, setUser] = useState({});

  const getUser = async () => {
    const results = await fetch("https://randomuser.me/api/");
    const {
      results: [result]
    } = await results.json();
    setUser(result);
  };

  useEffect(() => {
    getUser();
  }, []);

  return <div className="App">{JSON.stringify(user)}</div>;
}

We have the user state with the useState hook and it’s set to an empty object.

Then we define the getUser function that calls fetch to make a GET request.

We call results.json() method to get the JSON response.

And then we call setUser function to set the response as the value of the user state.

Then in the useEffect hook, we call getUser to make the request.

The empty array lets us run the useEffect callback when App mounts.

And then we show the value to the user.

API Call Whenever Some Prop or State Changes

To make an API call whenever some prop or state changes, we can write:

import { useEffect, useState } from "react";

export default function App() {
  const [id, setId] = useState(1);
  const [todo, setTodo] = useState({});

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

  useEffect(() => {
    getTodo();
  }, [id]);

  return (
    <div className="App">
      <button onClick={() => setId((id) => id + 1)}>increment id</button>
      <p>{JSON.stringify(todo)}</p>
    </div>
  );
}

We have the id and todo states.

We want to make the API call to get the data with the id value.

To make the request, we call fetch with the URL string with the id .

Then we call setTodo with the data .

Then we call useEffect with a callback to call the getTodo function.

And we pass in the [id] array into useEffect .

Below that, we have a button to call setId to change the id value.

And we display the todo value below that.

Now when we click the buttons, we show the latest response after making the request with the given id .

To watch props and make requests when a prop’s value is updated, we can write:

import { useEffect, useState } from "react";

const Todo = ({ id }) => {
  const [todo, setTodo] = useState({});

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

  useEffect(() => {
    getTodo();
  }, [id]);

return <p>{JSON.stringify(todo)}</p>;
};

export default function App() {
  const [id, setId] = useState(1);

  return (
    <div className="App">
      <button onClick={() => setId((id) => id + 1)}>increment id</button>
      <Todo id={id} />
    </div>
  );
}

We have the Todo component that takes the id prop.

And the rest of the code is the same as the previous example.

Conclusion

We can make API calls within React components created with hooks with the useEffect hook.

Categories
React

How to Send Data From Child to Parent Component with React Hooks?

Sending data from a child component to a parent component is an operation that we sometimes want to do.

We can send data from a child component to its parent easily.

In this article,e we’ll look at how to send data from the child component to the parent component with components that are made with React hooks.

Send Data From Child to Parent Component

We can send data from the child component to the parent by passing a function from the parent component to its child as a prop.

Then the child component can call the component from the prop to send the data to the parent.

For instance, we can write:

import { useCallback, useState } from "react";

const Counter = ({ parentCallback }) => {
  const [count, setCount] = useState(0);

  return (
    <button
      onClick={() => {
        setCount((count) => count + 1);
        parentCallback(count + 1);
      }}
    >
      increment
    </button>
  );
};

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

  const callback = useCallback((count) => {
    setCount(count);
  }, []);

  return (
    <div className="App">
      <Counter parentCallback={callback} />
      <h2>count {count}</h2>
    </div>
  );
}

We have the Counter value which takes the parentCallback prop.

We defined the count state which we update when we click on the increment button.

The onClick prop of the button to call setCount with a callback to return the new count value.

Also, we call the parentCallback with count + 1 to send the latest count value to the App component.

In App component, we also have the count state.

And we create a callback with the useCallback hook with the function we want to call.

It returns the callback from the first argument.

The callback calls setCount to update count from the count parameter.

The 2nd argument is the dependencies, which is empty because it doesn’t depend on anything.

Then we call in callback as the value of the parentCallback prop in Counter .

And we see the count below the button.

Conclusion

We pass values from a child component to the parent by passing a function from the parent to the child as a prop.

Then we can call the function with arguments set to the data we want to pass to the parent.

And in the parent component, we can do what we want with the data.

Categories
React

How to Run the useEffect React Hook Callback Only on State Update?

The useEffect hook lets us watch the values of states and props and do something according to their values.

Sometimes we may only want to run the useEffect callback when a state value has been updated.

In this article, we’ll look at how to only run the useEffect hook callback only when a state value is updated.

Run the useEffect React Hook Callback Only on State Update

To run the useEffect hook callback only when a state is updated, we can create a ref to keep track of when a state is updated.

For instance, we can write:

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

export default function App() {
  const isInitialMount = useRef(true);
  const [count, setCount] = useState(0);

  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
    } else {
      console.log(count);
    }
  });

  return (
    <form>
      <button onClick={() => setCount((c) => c + 1)}>increment</button>
    </form>
  );
}

We create the isInitialMount ref with the useRef hook which is set to true initially.

Then we create the count state which we want to log only when count is updated.

In the useEffect callback, we check is isInitialMount.current is true .

If it’s true , then we set initialMount.current to false .

Refs are non-reactive, so it won’t cause a re-render of the component.

However, the current value persists across renders.

When isIninitialMount.current is false , we log the value of count .

Below that, we have a button that calls setCount to update the count value when we click it.

Now when we click the increment button, we see count is logged starting when it’s 1, which means it’s updated beyond its initial value.

We can also extract the logic into its own hook.

For instance, we dcan write:

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

const useUpdateEffect = (effect, dependencies = []) => {
  const isInitialMount = useRef(true);

  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
    } else {
      effect();
    }
  }, dependencies);
};

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

  useUpdateEffect(() => {
    console.log(count);
  }, [count]);

  return (
    <form>
      <button onClick={() => setCount((c) => c + 1)}>increment</button>
    </form>
  );
}

We have the useUpdateEffect hook that takes the effect function, which we want to run when anything in the dependencies array change.

We move the isInitialMount ref to the hook.

And we call useEffect in useUpdateEffect hook instead of the App component.

This lets us reuse the logic anywhere with ease.

Conclusion

We can add a ref to keep track of when a component is updated when running the useEffect callback code we want accordingly when it does.

This lets run the useEffect callback only when the component is updated.

Categories
React

How to Handle Inputs with React Hooks?

Handling input values is something that we’ve to do often in our React app.

In this article, we’ll look at how we can handle inputs in our React components.

Handling Inputs

To handle inputs, we can write:

import { useState } from "react";

const initialState = {
  username: "",
  email: "",
  password: ""
};

export default function App() {
  const [{ username, email, password }, setState] = useState(initialState);

  const onChange = (e) => {
    const { name, value } = e.target;
    setState((prevState) => ({ ...prevState, [name]: value }));
  };

  return (
    <form>
      <div>
        <label>
          Username:
          <input value={username} name="username" onChange={onChange} />
        </label>
      </div>
      <div>
        <label>
          Email:
          <input value={email} name="email" onChange={onChange} />
        </label>
      </div>
      <div>
        <label>
          Password:
          <input
            value={password}
            name="password"
            type="password"
            onChange={onChange}
          />
        </label>
      </div>
      <button>Submit</button>
    </form>
  );
}

We create a state with the useState hook.

Its initial value is set to an object with the username , email , and password properties.

Then we have the onChange function to update the value of the state.

We call setState with a callback to get the prevState which is the state’s current value.

And we return a new object which is a copy of prevState , but with the [name ] dynamic property set to e.target.value .

e.target.value has the inputted value.

Below that, we have the inputs with the value prop to set the input value of those input fields.

And the onChange prop is set to the onChange function which lets us update the state to what we want.

Conclusion

We can handle input values by getting the value that’s typed in with e.target.value .

Then we can update the state object with the new value by making a copy of it and overwriting the property value we want with a callback in the state setter function.