How use async return value from useEffect as default value in useState?
I've created a simple example https://codesandbox.io/s/4zq852m7j0.
As you can see I'm fetching some data from a remote source. I'd like to use the return value as the value inside my textfield.
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);
,
[value]
);
return value;
;
However using the value inside the useState
function does not work. I think useState
uses the default value only on first render. When first rendering the value is obviously not set since it's async. The textfield should have the value bar
but it is empty.
function App()
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event =>
setName(event.target.value);
;
return (
<div className="App">
<p>remote name: remoteName</p>
<p>local name: name</p>
<input onChange=onChange value=name />
</div>
);
After fetching the value from remote I'd like to be able to change it locally.
Any ideas?
javascript reactjs react-hooks
add a comment |
I've created a simple example https://codesandbox.io/s/4zq852m7j0.
As you can see I'm fetching some data from a remote source. I'd like to use the return value as the value inside my textfield.
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);
,
[value]
);
return value;
;
However using the value inside the useState
function does not work. I think useState
uses the default value only on first render. When first rendering the value is obviously not set since it's async. The textfield should have the value bar
but it is empty.
function App()
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event =>
setName(event.target.value);
;
return (
<div className="App">
<p>remote name: remoteName</p>
<p>local name: name</p>
<input onChange=onChange value=name />
</div>
);
After fetching the value from remote I'd like to be able to change it locally.
Any ideas?
javascript reactjs react-hooks
add a comment |
I've created a simple example https://codesandbox.io/s/4zq852m7j0.
As you can see I'm fetching some data from a remote source. I'd like to use the return value as the value inside my textfield.
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);
,
[value]
);
return value;
;
However using the value inside the useState
function does not work. I think useState
uses the default value only on first render. When first rendering the value is obviously not set since it's async. The textfield should have the value bar
but it is empty.
function App()
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event =>
setName(event.target.value);
;
return (
<div className="App">
<p>remote name: remoteName</p>
<p>local name: name</p>
<input onChange=onChange value=name />
</div>
);
After fetching the value from remote I'd like to be able to change it locally.
Any ideas?
javascript reactjs react-hooks
I've created a simple example https://codesandbox.io/s/4zq852m7j0.
As you can see I'm fetching some data from a remote source. I'd like to use the return value as the value inside my textfield.
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);
,
[value]
);
return value;
;
However using the value inside the useState
function does not work. I think useState
uses the default value only on first render. When first rendering the value is obviously not set since it's async. The textfield should have the value bar
but it is empty.
function App()
const remoteName = useFetch();
// i want to see the remote value inside my textfield
const [name, setName] = useState(remoteName);
const onChange = event =>
setName(event.target.value);
;
return (
<div className="App">
<p>remote name: remoteName</p>
<p>local name: name</p>
<input onChange=onChange value=name />
</div>
);
After fetching the value from remote I'd like to be able to change it locally.
Any ideas?
javascript reactjs react-hooks
javascript reactjs react-hooks
edited Nov 21 '18 at 20:47
skyboyer
3,73311229
3,73311229
asked Nov 14 '18 at 10:59
zemircozemirco
11.9k44374
11.9k44374
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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
add a comment |
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>
);
Whenbar
is an empty string (remove the value inside the text field) the whole component is gone.
– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can useuseState()
and doname != null && ...
check instead.
– estus
Nov 14 '18 at 11:37
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53298626%2fhow-use-async-return-value-from-useeffect-as-default-value-in-usestate%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
add a comment |
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
add a comment |
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
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
answered Nov 14 '18 at 11:39
Shubham KhatriShubham Khatri
84.7k15102142
84.7k15102142
add a comment |
add a comment |
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>
);
Whenbar
is an empty string (remove the value inside the text field) the whole component is gone.
– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can useuseState()
and doname != null && ...
check instead.
– estus
Nov 14 '18 at 11:37
add a comment |
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>
);
Whenbar
is an empty string (remove the value inside the text field) the whole component is gone.
– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can useuseState()
and doname != null && ...
check instead.
– estus
Nov 14 '18 at 11:37
add a comment |
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>
);
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>
);
edited Nov 14 '18 at 11:23
answered Nov 14 '18 at 11:07
estusestus
72.6k22106224
72.6k22106224
Whenbar
is an empty string (remove the value inside the text field) the whole component is gone.
– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can useuseState()
and doname != null && ...
check instead.
– estus
Nov 14 '18 at 11:37
add a comment |
Whenbar
is an empty string (remove the value inside the text field) the whole component is gone.
– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can useuseState()
and doname != null && ...
check instead.
– estus
Nov 14 '18 at 11:37
When
bar
is an empty string (remove the value inside the text field) the whole component is gone.– zemirco
Nov 14 '18 at 11:34
When
bar
is an empty string (remove the value inside the text field) the whole component is gone.– zemirco
Nov 14 '18 at 11:34
If using empty string as initial state doesn't serve your purpose, don't use it. You can use
useState()
and do name != null && ...
check instead.– estus
Nov 14 '18 at 11:37
If using empty string as initial state doesn't serve your purpose, don't use it. You can use
useState()
and do name != null && ...
check instead.– estus
Nov 14 '18 at 11:37
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53298626%2fhow-use-async-return-value-from-useeffect-as-default-value-in-usestate%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown