javascript - Can you use an async function to set initial state with useState - Stack Overflow

My ponent relies on local state (useState), but the initial value should e from an http response.Can I

My ponent relies on local state (useState), but the initial value should e from an http response.

Can I pass an async function to set the initial state? How can I set the initial state from the response?

This is my code

  const fcads = () => {
    let good;
    Axios.get(`/admin/getallads`).then((res) => {
      good = res.data.map((item) => item._id);
    });
    return good;
  };

  const [allads, setAllads] = useState(() => fcads());

But when I try console.log(allads) I got result undefined.

My ponent relies on local state (useState), but the initial value should e from an http response.

Can I pass an async function to set the initial state? How can I set the initial state from the response?

This is my code

  const fcads = () => {
    let good;
    Axios.get(`/admin/getallads`).then((res) => {
      good = res.data.map((item) => item._id);
    });
    return good;
  };

  const [allads, setAllads] = useState(() => fcads());

But when I try console.log(allads) I got result undefined.

Share Improve this question edited Dec 22, 2020 at 13:05 kidroca 3,9162 gold badges32 silver badges45 bronze badges asked Dec 21, 2020 at 9:32 test tettest tet 931 gold badge1 silver badge3 bronze badges 5
  • Where did you do console.log(allads)? – MacOS Commented Dec 21, 2020 at 9:36
  • I make a button and do onclick to console.log(allads) @MacOS – test tet Commented Dec 21, 2020 at 9:42
  • Use a useEffect hook and make the server call inside that. – adiga Commented Dec 21, 2020 at 9:42
  • Also, you can't use good = res.data inside the callback and return good outside. return is called before the callback is run. How do I return the response from an asynchronous call? – adiga Commented Dec 21, 2020 at 9:46
  • I tried as you said but still got undefined @adiga – test tet Commented Dec 21, 2020 at 9:54
Add a ment  | 

2 Answers 2

Reset to default 4

If you use a function as an argument for useState it has to be synchronous.

The code your example shows is asynchronous - it uses a promise that sets the value only after the request is pleted

You are trying to load data when a ponent is rendered for the first time - this is a very mon use case and there are many libraries that handle it, like these popular choices: https://www.npmjs./package/react-async-hook and https://www.npmjs./package/@react-hook/async. They would not only set the data to display, but provide you a flag to use and show a loader or display an error if such has happened

This is basically how you would set initial state when you have to set it asynchronously

const [allads, setAllads] = useState([]);
const [loading, setLoading] = useState(false);

React.useEffect(() => {
  // Show a loading animation/message while loading
  setLoading(true);

  // Invoke async request
  Axios.get(`/admin/getallads`).then((res) => {
    const ads = res.data.map((item) => item._id);
    // Set some items after a successful response
    setAllAds(ads):
  })
  .catch(e => alert(`Getting data failed: ${e.message}`))
  .finally(() => setLoading(false))
// No variable dependencies means this would run only once after the first render
}, []);

Think of the initial value of useState as something raw that you can set immediately. You know you would be display handling a list (array) of items, then the initial value should be an empty array. useState only accept a function to cover a bit more expensive cases that would otherwise get evaluated on each render pass. Like reading from local/session storage

const [allads, setAllads] = useState(() => {
  const asText = localStorage.getItem('myStoredList');
  const ads = asText ? JSON.parse(asText) : [];
  return ads;
});

You can use the custom hook to include a callback function for useState with use-state-with-callback npm package.

npm install use-state-with-callback

For your case:

import React from "react";
import Axios from "axios";
import useStateWithCallback from "use-state-with-callback";

export default function App() {
  const [allads, setAllads] = useStateWithCallback([], (allads) => {
    let good;
    Axios.get("https://fakestoreapi./products").then((res) => {
      good = res.data.map((item) => item.id);
      console.log(good);
      setAllads(good);
    });
  });

  return (
    <div className="App">
      <h1> {allads} </h1>
    </div>
  );
}


Demo & Code: https://codesandbox.io/s/distracted-torvalds-s5c8c?file=/src/App.js

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744215216a4563522.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信