How use async return value from useEffect as default value in useState?

Now that useFetch returns a value that is available asynchronously, what you need is to update localState when the remoteValue is available, for that you can write an effect

const remoteName = useFetch();
  // i want to see the remote value inside my textfield
  const [name, setName] = useState(remoteName);
  useEffect(
    () => {
      console.log("inside effect");
      setName(remoteName);
    },
    [remoteName] // run when remoteName changes
  );

  const onChange = event => {
    setName(event.target.value);
  };

Working demo


This is exactly same case as setting initial state asynchronously in class component:

state = {};

async componentDidMount() {
  const response = await fetch(...);
  ...
  this.setState(...);
}

Asynchronously retrieved state cannot be available during initial render. Function component should use same technique as class component, i.e. conditionally render children that depend on a state:

  return name && <div className="App">...</div>;

This way there's no reason for useFetch to have its own state, it can maintain common state with the component (an example):

const useFetch = () => {
  const [value, setValue] = useState("");

  useEffect(
    async () => {
      const response = await fetch("https://httpbin.org/get?foo=bar");
      const data = await response.json();
      setValue(data.args.foo);
    },
    [] // executed on component mount
  );

  return [value, setValue];
};

function App() {
  const [name, setName] = useFetch();

  const onChange = event => {
    setName(event.target.value);
  };

  return name && (
    <div className="App">
      <p>local name: {name}</p>
      <input onChange={onChange} value={name} />
    </div>
  );
}