Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

137
Views
How can I unrender a component conditionally?

In my application I want to only display a component if two conditions are true. From the parent, this is what it looks like:

 {!online ? (
       <TouchableOpacity
           onPress={changeOnlineStatus}
       >
       <Text>
           Go online
       </Text>
       </TouchableOpacity>
  ) : online && queue === 0 ? (
       <TouchableOpacity
           onPress={changeOnlineStatus}
       >
            <Text>
                  Go offline
            </Text>
       </TouchableOpacity>
  ) : (
       <Service
           details={userDetails.queueItems[0].details}
       />
)}

Here, changeOnlineStatus status simply changes the online variable so that the two TouchableOpacities switch. The problem is the Service component. It should only be rendered if the queue is populated, but the queue exists as an array in a constants file. In the Service component's file, the queue is changed by a timer with the following states/hooks:

// timer value of 5
const [timeRemaining, setTimeRemaining] = useState(5);

// timer counts down to 0 and then removes the first element of the array
    useEffect(() => {
        setTimeout(() => {
            if (timeRemaining > 0) {
                setTimeRemaining(timeRemaining - 1);
            } else {
                userDetails.queueItems.shift();
                return;
            }
        }, 1000);
    }, [timeRemaining]);

So when the time runs out, the array has no elements, but the Service component stays rendered. Why isn't it removed since the condition (a populated array) is no longer true?

If it's important, the queue exists in a constants file and looks like this:

queueItems: [
    {
        title: "Test",

    },
]
about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Components are rendered only when state or props are changing, you need to define the queue as a state in the parent component and inject the queue and the setQueue to the Service Component.

about 4 years ago · Santiago Trujillo Report

0

I found a solution for this. As another user said, it has to do with mutating the state of the array (or an object) without changing its reference. A more detailed explanation can be found here.

The fix is super easy and involves making a copy of the array with the spread operator like so:

const [queue, setQueue] = useState(userDetails.queueItems);
const copiedQueue = [...queue];

Since React will only rerender when the reference has changed, simply editing the array/object won't trigger a rerender since the reference for JavaScript arrays and objects is not changed when the array or object is changed.

This can only be achieved by creating a copy of the array or object, and that copy will have a different reference. So, when I need the state to change for this array, instead of changing it directly with setQueue I should have been updating copiedQueue and setting the state of queue with copiedQueue like so:

copiedQueue.shift();
setQueue(copiedQueue);

And since I was making this change in a separate component, I simply needed to pass a prop to the component so I could update the state from there. I changed:

const [timeRemaining, setTimeRemaining] = useState(5);

    useEffect(() => {
        setTimeout(() => {
            if (timeRemaining > 0) {
                setTimeRemaining(timeRemaining - 1);
            } else {
                userDetails.queueItems.shift();
                return;
            }
        }, 1000);
    }, [timeRemaining]);

To:

useEffect(() => {
    setTimeout(() => {
        if (timeRemaining > 0) {
            setTimeRemaining(timeRemaining - 1);
        } else {
            // this is the prop passed in the parent
            // in the parent it's a function that updates the state
            onChange(true);
            return;
        }
    }, 1000);
}, [timeRemaining]);

I hope this helps someone in the future!

about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!