-1

I try to give data with param using Route and using param, get data from server and print it. but useEffect doesn't work

export default function Board({ match }) {
  const [content, setContent] = useState([]);

  useEffect(() => {
    getOnePost(match.params.number).then((response) => {
      setContent(response);
    });
    console.log(content);
  }, []);

  return (
    <div>
      <div>hi</div>
    </div>
  );
}
          <PrivateRoute
            path="/board/:number"
            authenticated={this.state.authenticated}
            component={Board}
          />

enter image description here

Dean97K
  • 60
  • 5
  • The `useEffect` callback code is 100% synchronous, so it won't, and can't, wait for the Promise chain to resolve and enqueue the state update. Also, even if you moved the console log ***into*** the Promise chain, because React state updates are asynchronously processed you'll still only log the state from the current render cycle, not what it will be on a later render cycle after it's processed. – Drew Reese Jul 31 '21 at 04:12

5 Answers5

0

I think you need to receive the url parameters from the useParams hook.

import { useParams } from "react-router-dom";

export default function Board() {
  ...

  const { number } = useParams(); // get url parameters 

  useEffect(() => {
    getOnePost(number).then((response) => {
      setContent(response);
    });
    console.log(content);
  }, []);

  ...

}
Badal Saibo
  • 2,499
  • 11
  • 23
0

I think getonepost function is not defined as a async function. Please use this code.

useEffect(() => {
getOnePost(match.params.number).then((response) => {
  setContent(response);
  console.log(content);
});

}, []); or you can try this either.

const [ update, setUpdate]=useState(true);

 useEffect(() => {
          console.log(content);
        });
        
      }, [update]);

    getOnePost(match.params.number).then((response) => {
          setContent(response);
          setUpdate(!update);
    }
pullidea-dev
  • 1,768
  • 1
  • 7
  • 23
0

You should pass match.params.number to useEffect as second argument.

 useEffect(() => {
    getOnePost(match.params.number).then((response) => {
      setContent(response);
    });
    console.log(content);
  }, [match.params.number]);
Ahmad
  • 816
  • 2
  • 9
  • 15
0

getOnePost is an asynchronous promise. So attempting to console.log(content) on the next line will not wait for the promise to resolve, and will log the initial value of [].

This is expected behaviour.

If you really want to log the value of content when it changes, add another useEffect with a dependency on content and put the console.log there.

export default function Board({ match }) {
  const [content, setContent] = useState([]);

  useEffect(() => {
    getOnePost(match.params.number).then((response) => {
      setContent(response);
    });
  }, []);

  useEffect(() => {
    console.log(content);
  }, [content])

  return (
    <div>
      <div>hi</div>
    </div>
  );
}
ksav
  • 20,015
  • 6
  • 46
  • 66
0

see, you are using console.log outside the .then statement, as you are writing asynchronous code it will console.log the content first then make a request to the server. if you want to see response, console.log it inside the then statement like this:-

  const [content, setContent] = useState([]);

  useEffect(() => {
    getOnePost(match.params.number).then((response) => {
      setContent(response);
      console.log(response);
    });
    
  }, []);

and if you want to check weather it is stored in state or not you can do this:-

const [content, setContent] = useState([]);

  useEffect(() => {
    getOnePost(match.params.number).then((response) => {
      setContent(response);
    });
    
  }, []);
useEffect(() => {
   console.log(content)
}, [content])

the first useEffect run to get data from api and second run when content state changes.

Dharman
  • 30,962
  • 25
  • 85
  • 135