0

In my react js application i use react-select => library. https://react-select.com/home#getting-started

import "./styles.css";
import Select from 'react-select'
import { useState, useEffect } from "react";
export default function App() {
  const [state, setState] = useState();
 
  useEffect(() => {
    const response = fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(json => setState(json?.map((i) => {
      return {label: i.name, value: i.name}
    })))
  },[])
  console.log(state?.[0])
  return (
    <div className="App">
      <Select
      defaultValue={state?.[0]} //expect the first value that comes from back-end
      options={state} 
      /> 
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

How you can notice i set as initial value the first value that comes from api defaultValue={state?.[0]}, but the value does not appear as default value, even in the console.log it appears. I assume that this happens because of undefined value on the first render, so in the first render state?.[0] is undefined, but after that the value appears in the console. How to get the initial value inside the select?
demo: https://codesandbox.io/s/hopeful-keldysh-6xynq?file=/src/App.js:0-705

3
  • I don't think you saved your codesandbox link. it's showing the default starter code Commented Dec 1, 2021 at 20:19
  • @azium i saved now Commented Dec 1, 2021 at 20:32
  • great. @CHess answer is exactly right. because it doesn't "update" the default value because it keeps whatever it had from the first render. putting if (!state) return null fixes it Commented Dec 1, 2021 at 20:44

1 Answer 1

1

You are correct that the useEffect makes the API call after the first render. For most cases, this is a good thing, as it allows you render content, such as a loading spinner, while you are waiting for the API call to finish:

export default function App() {
  const [state, setState] = useState();
 
  useEffect(() => {
    const response = fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(json => setState(json?.map((i) => {
      return {label: i.name, value: i.name}
    })))
  },[])

  if (!state) {
      // you can display a loading spinner here if you want
      return null;
  }

  // Once we've reached this point on subsequent renders, state should be defined
  return (
    <div className="App">
      <Select
      defaultValue={state.[0]} //expect the first value that comes from back-end
      options={state} 
      /> 
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

Also note that because you are using defaultValue, it is essential that you have state defined at the time the Select component is initially rendered/mounted as subsequent changes that you send to defaultValue will not affect the current value (as the value was already "defaulted" to undefined).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.