1

So basically i started learning ReactJs and am trying to build a chatting app now here there is section of adding Channels so here is my code

const [Channels, setChannelState] = React.useState([])
let loadedChannels = []
 React.useEffect(() => {

        setCurrentUser(props.currentUser)

        ref.ref('channels').on('child_added', snap =>{

            loadedChannels.push(snap.val())
            console.log(loadedChannels) 
            setChannelState(loadedChannels) 

        })



  },[])

so here when i tried to log the loadedChannels Array am getting all the result but when i try to set this array to my state then am getting only one result how can i resolve this?

6
  • Try removing [] from your useEffect. Commented Sep 6, 2019 at 13:57
  • try removing [] or append '[Channels]' so that when Channels change then only function passed to useEffect will run. Commented Sep 6, 2019 at 14:06
  • @DarpanRangari I tried your method but am getting infinite Loop Commented Sep 6, 2019 at 14:08
  • @HimanshuRahi you have channels state, how it looks like? when it changes then it will trigger useEffect again. can you share the same here. Commented Sep 6, 2019 at 14:14
  • When it load first the i will get Only one array in Channels State and when anything will change in page then am getting all result in Channels state @DarpanRangari Commented Sep 6, 2019 at 14:23

3 Answers 3

3

You have an empty array [] as a second parameter which runs the function passed to useEffect only once.

You can tell React to skip applying an effect if certain values haven’t changed between re-renders. To do so, pass an array as an optional second argument to useEffect which you have done.

If we pass [] as second parameter this will apply effect only once.

We can pass value inside array, only on change which it will trigger useEffect call.

As per the documentation

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

try using something like this:

const [Channels, setChannelState] = React.useState([])

 React.useEffect(() => {
        let loadedChannels = []
        setCurrentUser(props.currentUser)

        ref.ref('channels').on('child_added', snap =>{

            loadedChannels.push(snap.val())

        })
       setChannelState([...loadedChannels]) 
},[])

Hope this helps, Happy coding!!!

Sign up to request clarification or add additional context in comments.

8 Comments

It's Not working, when page loads am getting zero result and when something changes in page then i will get all result in arrary
@HimanshuRahi use spread operator in setChannelState([...loadedChannels])
you are welcome @HimanshuRahi , this happend because you are returning the same object (to React) to update the state (i.e., loadedChannels) - you have mutated the object - this won't cause a re-render. If you de-structure the array [...loadedChannels] this is a new object and causes the re-render. have a look at my answer here for more detail stackoverflow.com/questions/57507594/…
so here the page re-render whenever the new value is added to loadedChannels ?? but in my app i have to set a redux state whenever the page loads but this setting my redux state multiple times. is there any way to set redux state only once??
Channels is the local state not in the redux state, which you have updated by setChannelState, if you want you update state in redux store that also you can do here, instead of using setChannelState dispatch an action which will then update store. Also you will then have update all the reference of Channels state in your component.
|
0

The second argument for useEffect is called a dependency array. And when it's empty, it acts like componentDidMount() i.e it runs only once, after the first render.

You also need to be careful about setting state in useEffect, since this might create an infinite loop of re-renders if not done correctly - setCurrentUser. That is not enough code to help any further than that.

This is the perfect time to get into React. Have fun!

Comments

0

Second parameter is passed for conditional rendering. To understand that there are few scenarios which tell us the possible ways to use that.

There are multiple scenarios which will make it easier for you to understand the importance and functionality of the second parameter with the help of the example from demo.

Scenario 1

Second parameter as empty array,

useEffect(() => {     
    console.log(`You clicked ${count} times`);     
  },      
[ ])            //called only once similar to componentDidMount     

If we pass an empty array, it means that we are not interested in monitoring any of the values so that the useEffect won’t be called except on mounting and before un-mounting. This mimic’s the working of componentDidMount and componentWillUnmount, it will only run once.

Scenario 2

Second parameter with value(s),

useEffect(() => {     
   console.log(`You clicked ${count} times`);     
}, [count]);      //function inside useEffect will be called when "count" will be updated     

The value passed as the second parameter (array) here in our example: count will be responsible for the execution of the function inside the useEffect Hook. If the value inside the array will be updated, then and only then the function will be executed.

What if we have multiple useEffect hooks and we need to update just few of them? Conditional rendering comes in light. Conditional rendering is achieved by passing the second parameter instead of just empty array. The values in the array will be monitored and the useEffect function will only be called when the monitored value(s) is/are updated.

Refer these links for more info https://stackblitz.com/edit/react-hooks-intro https://www.c-sharpcorner.com/article/react-hooks-introduction/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.