-1

I am getting infinite requests on my network, and it's due to my useEffect. I know that the problem is because I am putting in the brackets as the second argument the 'posts' and the 'setPost' inside the useEffect function, but I need the page to render whenever I add a new post, so the 'posts' must be inside the brackets.

    function Home() {
const {userData, setUserData} = useContext(userContext)
const [posts, setPost] = useState([])
const [createPost, setCreatePost] = useState('')
const handleToken = () => {
    localStorage.removeItem('auth-token')
}

const token = localStorage.getItem("auth-token");

const handleOnSubmit = (e) => {
    e.preventDefault()
    axios.post('http://localhost:5000/posts', {textOfThePost: createPost}, {
        headers: { 'auth-token': token },
    })
    .then((res) => {setCreatePost("")})
    axios.get('http://localhost:5000/posts')
    .then(res => {
        setPost(res.data)
    })
}

useEffect(() => {
}, [posts])
  • you want to re-render when you add a new post? – malong11 Nov 02 '20 at 17:47
  • You don't need to use useEffect here. You can just update the state. – Bonzo Nov 02 '20 at 17:48
  • @malong11 yes! just like twitter – gonzalovc15 Nov 02 '20 at 17:49
  • @RunSmeagolRun what do you mean? All the post should appear as soon as the page load, that's why I'm using useEffect – gonzalovc15 Nov 02 '20 at 17:49
  • @RunSmeagolRun is right you dont need useState here. just make a get request after you add a new post and update the state it should re-render itself since the state is updated – malong11 Nov 02 '20 at 17:52
  • @gonzalovc15 as explained in above comment :) – Bonzo Nov 02 '20 at 17:56
  • its not working, im putting the get request in the function and leaving useEffect empty with just the [posts] as the second argument, but if I refresh the page the posts doesn't appear until I create a new post – gonzalovc15 Nov 02 '20 at 18:05
  • can you update the post with your current solution? – Bonzo Nov 02 '20 at 18:16
  • If you really want to show new entries in your database you need to consider something similar to a snapshot listener. Basically a function that will be triggered (in the frontend) by your database with the updated values. Take firestore real time updates as an example https://firebase.google.com/docs/firestore/query-data/listen – Julian Kleine Nov 02 '20 at 18:19
  • How would the `posts` array get updated when someone else (on a different device, different state etc) is adding a post. – Julian Kleine Nov 02 '20 at 18:20
  • @RunSmeagolRun there i updated – gonzalovc15 Nov 02 '20 at 18:24
  • When you update the post state, do it like this `setPost([ ...post, res.data ])` – Bonzo Nov 02 '20 at 18:30
  • that doesn't make the post appear when I load the page, still have to execute the function to them appear – gonzalovc15 Nov 02 '20 at 18:39

2 Answers2

0

If you're doing setPost inside useEffect, I assume posts being changed, and you've added posts as dependency in useEffect, Of course which will re-call and it goes infinite loop. Make sure when do you want to call posts API.

const [posts, setPost] = useState([])

useEffect(() => {
   axios.get('http://localhost:5000/posts')
   .then(res => {
     setPost(res.data) // Which will change `posts`
   })
}, [posts]) // this will trigger useEffect and It goes infinite loop
// Change it to
useEffect(() => {
   axios.get('http://localhost:5000/posts')
   .then(res => {
     setPost(res.data) // Which will change `posts`
   })
}, []) -> Which call only one time

Naren
  • 4,152
  • 3
  • 17
  • 28
  • I said that that won't be a solution for me cause I need to update the page when a new post is created, and leaving the brackets empty avoid that to happen – gonzalovc15 Nov 02 '20 at 18:23
  • 2
    you've just changed your question!, you didn't ask for this earlier. – Naren Nov 02 '20 at 18:40
0

This useEffects gets called everytime posts changes, and inside the useEffect you're changing posts value, so you got into an recursive loop.

  useEffect(() => {
    axios.get('http://localhost:5000/posts')
        .then(res => {
            setPost(res.data)
        })
    }, [posts])

If you want it to get called only once, you should leave the empty array in your effect, so it will only get called once when your component is mounted.

  useEffect(() => {
    axios.get('http://localhost:5000/posts')
        .then(res => {
            setPost(res.data)
        })
    }, [])
FLiotta
  • 151
  • 6
  • I said that that won't be a solution for me cause I need to update the page when a new post is created, and leaving the brackets empty avoid that to happen – gonzalovc15 Nov 02 '20 at 18:23