admin管理员组

文章数量:1335356

i have a problem with hooks.

i'm using react-hooks, i have a button which at onClick getting data from api and setState with it.

Problem is:

when i click to button first time i get response from api but can't set it to state. When click to button second time i can setState. Why it happened ?

here is my ponent look like:

function App() {
  const [a, setA] = useState(null);


  const fetchData = () => {
    let data = {
        id: 1
    }


    axios.post(baseUrl, data)
    .then(res => {
      if (res.data) {
        setA(res.data)
      }
      console.log(a)
    })

  }

  return (
    <div className="App">
      <div>
        <button onClick={fetchData}></button>
      </div>
    </div>
  );
}

export default App;

i tried to using fetchData function like that:

 function fetchData() {
        let data = {
            id: 1
        }


        axios.post(baseUrl, data)
        .then(res => {
          if (res.data) {
            setA(res.data)
          }
          console.log(a)
        })

      }

but it's not helped too

i have a problem with hooks.

i'm using react-hooks, i have a button which at onClick getting data from api and setState with it.

Problem is:

when i click to button first time i get response from api but can't set it to state. When click to button second time i can setState. Why it happened ?

here is my ponent look like:

function App() {
  const [a, setA] = useState(null);


  const fetchData = () => {
    let data = {
        id: 1
    }


    axios.post(baseUrl, data)
    .then(res => {
      if (res.data) {
        setA(res.data)
      }
      console.log(a)
    })

  }

  return (
    <div className="App">
      <div>
        <button onClick={fetchData}></button>
      </div>
    </div>
  );
}

export default App;

i tried to using fetchData function like that:

 function fetchData() {
        let data = {
            id: 1
        }


        axios.post(baseUrl, data)
        .then(res => {
          if (res.data) {
            setA(res.data)
          }
          console.log(a)
        })

      }

but it's not helped too

Share Improve this question asked Dec 15, 2019 at 12:54 user3348410user3348410 2,84311 gold badges56 silver badges91 bronze badges 9
  • @user3348410, you should use useEfect hook for fetching, because you work with an Asynchronous call. – Asking Commented Dec 15, 2019 at 13:00
  • how it will be @Asking – user3348410 Commented Dec 15, 2019 at 13:03
  • 1 setA() doesn't change a in that scope, but the fetch does work the first time. – Patrick Roberts Commented Dec 15, 2019 at 13:06
  • @AtulKumar that's the Fetch API, not axios. Axios doesn't have a json() async method. – Patrick Roberts Commented Dec 15, 2019 at 13:07
  • can you give me some example for my situation ? useEffect is like ponentDidMount not? i don't wan't fetch something in ponentDidmount i wan't fetch data when user click to button – user3348410 Commented Dec 15, 2019 at 13:10
 |  Show 4 more ments

4 Answers 4

Reset to default 4

a is a const. It's impossible to change it, so there's no way your console.log statement at the end of fetchData could ever log out something different than the value that a had when fetchData was created.

So that's not what setA does. The point of setA isn't to change the value of the const, but to cause the ponent to rerender. On that new render, a new set of variables will be created, and the new a will get the new value. Move your console.log out to the body of your ponent, and you'll see it rerender with the new value.

In short: Your code appears to be already working, you just have the wrong logging.

If your scope is to fetch data, use this:

const [data, setData] = useState("");
  useEffect(async () => {
    const result = await axios(
      'here will be your api',
    );
    setData(result.data);
  });

Now your response will be stored in data variable.

I would not use an effect for it, effects are useful if the props or state changes and can thereby substitute lifecycle methods like ponentDidMount, ponentDidUpdate, ponentWillUnmount, etc.. But in your case these props haven't changed yet (you want to change your state though). Btw, be aware that @Asking's approach will fetch data on EVERY rerender (props or state change). If you want to use useEffect, be sure to add the second parameter to tell React when to update.

Normally, your code should work, I haven't tested but looks legit. Have you used developer tools for react to check if the state/hook has changed? Because if you say it did not work because of the console.log printing: Have in mind that setA() is an async function. The state was most likely not yet changed when you try to print it. If you haven't react developer tools (which I highly remend) you can check the real state by adding this code in the function:

useEffect(() => console.log(a), [a]);

I have a few real improvements to your code though:

    function App() {
  const [a, setA] = useState(null);


  const fetchData = useCallback(async () => {
    let data = {
        id: 1
    }


    const res = await axios.post(baseUrl, data);
    setA(res.data);

  }, []);

  return (
    <div className="App">
      <div>
        <button onClick={fetchData}></button>
      </div>
    </div>
  );
}

export default App;

By adding useCallback you ensure that the function is memorized and not declared again and again on every rerender.

@Nicholas Tower has already answered your question. But if you are looking for code

function App() {
  const [a, setA] = useState(null);


  const fetchData = () => {
    let data = {
        id: 1
    }


    axios.post(baseUrl, data)
    .then(res => {
      if (res.data) {
        setA(res.data)
      }

    })

  }


  console.log(a)
  return (
    <div className="App">
      <div>
        <button onClick={fetchData}></button>
      </div>
    </div>
  );
}

export default App;

just place log before return (. This should do

本文标签: javascriptReact hooks not set state at first timeStack Overflow