creating a Boolean flag for onclick method - javascript

I am having some OOP issues that are probably pretty simple. I have a class that renders some html. However it has an onClick that calls a function that sets a flag inside the class if the image is clicked. Now here is the issue, when I render this class object and click the button from a separate js file, it stays false. I want it to permanently change the flag to true when clicked. here is the class...
class Settings extends React.Component {
handleClick() {
this.flag = true;
console.log(this.flag)
}
render(){
return(
<img src="./img/leaf.png" alt="" onClick={() => this.handleClick()}/>
);
}
}
and here is the code that calls it from a separate file...
const settingsObj = new Settings();
console.log(settingsObj.flag);
I want the flag to be false until the button is clecked and then it permamently changes to true. But it only goes true until my page rerenders as new data comes in and it resets to false. I have tried constructors and a few other techniques with no success.

Normal OOP design principles don't always apply directly to React components. Components don't usually have instance properties, they mostly just have props and state (there are a few exceptions where you do use an instance property, like Animation objects in react-native, but these are rare).
You're kind of mixing the two things in a way that doesn't quite make sense here. Settings is a React component that renders an image, but it's also an object which you instantiate by calling new Settings(). If there are other components which depend on the value of flag, you might want to separate the accessing and storing of the flag from the render component, passing a value and a callback to the renderer.
const Settings = ({setFlag}) => {
return(
<img src="./img/leaf.png" alt="" onClick={() => setFlag(true)}/>
);
}
You've suggested that you like the Context API as a solution for making the flag value globally available. There are a few ways to set this up, but here's one.
Outside of any component, we create a FlagContext object that has two properties: a boolean value flag and callback function setFlag. We need to give it a default fallback value, which is hopefully never used, so our default callback just logs a warning and does nothing.
const FlagContext = createContext<FlagContextState>({
flag: false,
setFlag: () => console.warn("attempted to use FlagContext outside of a valid provider")
});
This FlagContext object gives up Provider and Consumer components, but it's up to us to give a value to the FlagContext.Provider. So we'll create a custom component that handles that part. Our custom FlagProvider uses a local state to create and pass down the value. I've used a function component, but you could use a class component as well.
const FlagProvider = ({children}) => {
const [flag, setFlag] = useState(false);
return (
<FlagContext.Provider value={{
flag,
setFlag
}}>
{children}
</FlagContext.Provider>
)
}
We want to put the entire App inside of the FlagProvider so that the whole app has the potential to access flag and setFlag, and the whole app gets the same flag value.
When you want to use the value from the context in a component, you use either the useContext hook or the Consumer component. Either way, I like to creating an aliased name and export that rather than exporting the FlagContext object directly.
export const FlagConsumer = FlagContext.Consumer;
export const useFlagContext = () => useContext(FlagContext);
With the Consumer, the child of the consumer is a function that takes the value of the context, which in out case is an object with properties flag and setFlag, and returns some JSX.
This is usually a function you define inline:
const SomePage = () => {
return (
<FlagConsumer>
{({flag, setFlag}) => (<div>Flag Value is {flag.toString()}</div>)}
</FlagConsumer>
)
}
But it can also be a function component. Note that when using a function component as the child, you must pass the component itself ({Settings}) rather than an executed version of it (<Settings />).
const Settings = ({ setFlag }) => {
return <img src="./img/leaf.png" alt="" onClick={() => setFlag(true)} />;
};
const SomePage = () => {
return <FlagConsumer>{Settings}</FlagConsumer>;
};
The preferred method nowadays is with hooks. We call useFlagContext() inside the body of the function component and it returns our context object.
const SomePage = () => {
const {flag, setFlag} = useFlagContext();
return <Settings setFlag={setFlag}/>
};
Both the consumer and the hook only work if they are inside of a flag context provider, so that's why we put it around the whole app!
const App = () => {
return (
<FlagProvider>
<SomePage />
</FlagProvider>
);
};
Complete example on CodeSandbox

For this kind of interactions, I highly recommend you to use Redux
Another think I'm sure you will benefit from, is switching to hooks and function components: less boilerplate and much flexible code.
Back to the goal, using Redux your code would look similar to this:
const Settings = (props) => {
const dispatch = useDispatch();
const flag = useSelector(state => state.yourStoreObj.flag);
handleClick() {
dispatch(yourCustomAction("UPDATE_FLAG", true));
}
return(
<img src="./img/leaf.png" alt="" onClick={() => handleClick()}/>
);
}
Explanation:
First of all, spend 15 mins and get used to React Redux. Here's a good practical article to start with. If you're not familiar with hooks, start learning them as that will change a lot, while you don't need to change a single line of what you've done so far.
We suppose there's a property in the store that is the "flag" property of that specific element. In this way, the property can be read by the component itself with the useSelector() operator, or can be read anywhere in your application with the same methodology from any other component.
In the same way, you can change the value by dispatching a change (see dispatch() function) and in the same way, you can do that from any other components.
So, let's say you want to change that property when a click occurs on a completely different component, this is how the other component may looks like
const OtherCoolComp = (props) => {
const dispatch = useDispatch();
handleClick() {
dispatch(yourCustomAction("UPDATE_FLAG", true));
}
return(
<button onClick={() => handleClick()}>
Click me!
</button>
);
}
So you're dispatching the same action, setting it to the value you prefer, from a component that doesn't know who is displaying that value.

Related

Alternative to extending a functional component

I have the following component where within the useEffect, I am calling some data reading related
functions meant to happen once on load.
The problem is, some of the prop data are not available at this stage (still undefined) like the prodData and index.
They are only available when I get into the Nested components like <NestedComponent1 />.
I wish to move this logic into the nested components which will resolve this issue.
But I do not want to repeat these code inside the useEffect for each component. Instead looking to write these 7 lines once maybe in a function
and just call it with the 3 NestedComponents.
Issue is that there is a higher order function wrapping here plus all the values like prodData and index is coming from Redux store.
I can't just move all these logic inside useEffect into a normal JS function and instead need a functional component for this.
And if I make a functional component to perform these operations, I can't call it in the useEffect for each of the NestedComponents.
Cos this is not valid syntax.
React.useEffect(() => {
<NewlyCreatedComponentWithReadingFunctionality />
}, []);
Thus my query is, is there a way I could write a functional component which has the data reading logic inside its useEffect.
And then extend this functional component for each of the functional components so that the useEffect would just fire
when each of these NestedComponents are called?
Doesn't seem to be possible to do this thus looking for alternatives.
This is the existing component where some of these prop values are undefined at this stage.
const MyComponent = ({
prodData,
index,
country,
highOrder: {
AHigherOrderComponent,
},
}) => {
// this is the logic which I am looking to write once and be
// repeatable for all the NestedComponent{1,2,3}s below.
React.useEffect(() => {
const [, code] = country.split('-');
const sampleData = prodData[index].sampleData = sampleData;
const period = prodData[index].period = period;
const indication = prodData[index].indication = indication;
AHigherOrderComponent(someReadDataFunction(code, sampleData));
AHigherOrderComponent(someReadDataFunction(code, period);
AHigherOrderComponent(someReadDataFunction(code, indication);
}, []);
return (
{/* other logics not relevant */}
<div>
<div>
<NestedComponent1 />
<NestedComponent2 />
<NestedComponent3 />
</div>
</div>
);
};
export default connect( // redux connect
({
country,
prodData,
index,
}) => ({
country,
prodData,
index,
})
)(withHighOrder(MyComponent));
React components implement a pattern called composition. There are a few ways to share state between parts of your React application but whenever you have to remember some global state and offer some shared functionality, I would try and manage that logic inside a context provider.
I would try the following:
Wrap all your mentioned components inside a context provider component
Offer the someReadDataFunction as a callback function as part of the context
Within your provider, manage react state, e.g. functionHasBeenCalled that remembers if someReadDataFunction has been called already
Set functionHasBeenCalled to true inside someReadDataFunction
Call someReadDataFunction inside your components within a useEffect based on the props data
This way, your application globally remembers if the function has been executed already but you can still use the latest data within your useEffect within your components to call someReadDataFunction.

Using Variable from Props vs Passing Prop as Argument in React

In terms of writing components, which would be the preferred way to write below component? Assume that removeCard is outside of shown scope, ie. redux action.
My assumption would be that ComponentCardB would be, as it avoids passing an unnecessary argument which would be in the scope anyway. I imagine in terms of performance in the grand scheme of things, the difference is negligible, just more of a query in regards to best practise.
TIA
const ComponentCardA = (id) => {
const handleRemove = (cardId) => {
removeCard(cardId);
};
<div onClick={() => handleRemove(id)} />;
};
const ComponentCardB = (id) => {
const handleRemove = () => {
removeCard(id);
};
<div onClick={handleRemove} />;
};
With functional components like that, yes, there's no reason for the extra layer of indirection in ComponentCardA vs ComponentCardB.
Slightly tangential, but related: Depending on what you're passing handleRemove to and whether your component has other props or state, you may want to memoize handleRemove via useCallback or useMemo. The reason is that if other props or state change, your component function will get called again and (with your existing code) will create a new handleRemove function and pass that to the child. That means that the child has to be updated or re-rendered. If the change was unrelated to id, that update/rerender is unnecessary.
But if the component just has id and no other props, there's no point, and if it's just passing it to an HTML element (as opposed to React component), there's also probably no point as updating that element's click handler is a very efficient operation.
The second option is better way because using an arrow function in render creates a new function each time the component renders, which may break optimizations based on strict identity comparison.
Also if you don't want to use syntax with props.id you rather create function component with object as parameter:
const Component = ({id}) => { /* ... */ }
Of course using arrow function is also allowed but remember, when you don't have to use them then don't.

React: passing mapped data from button onclick to display on another component

I'm having some difficulty passing data that I have mapped from an API, it displays a bunch of Event cards based on how many events there are in the API array.
This my Event Cards component;
export default function EventCard() {
const classes = useStyles();
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios("http://localhost:23455/Event");
setData(result.data);
};
fetchData();
}, []);
const handleClick = (value) => () => {
console.log(value);
};
return (
<div>
<Row>
{" "}
{data.map((item) => (
<Card
className={classes.root}
style={{ marginRight: "25px", marginBottom: "25px" }}
>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
{item.icon}
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={item.name}
subheader="September 14, 2016"
/>
<CardMedia
className={classes.media}
image={LordsLogo}
title="Paella dish"
/>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
<p key={item.id}> {item.description}</p>
<p key={item.id}> {item.startDate}</p>
<p key={item.id}> {item.endDate}</p>
</Typography>
</CardContent>
<CardActions disableSpacing>
<IconButton aria-label="add to favorites">
<Button variant="outlined">Steward</Button>
</IconButton>
<IconButton aria-label="share">
<Button variant="outlined" onClick={handleClick({ item })}>
Tickets
</Button>
</IconButton>
</CardActions>
</Card>
))}
</Row>
</div>
);
}
I have an onclick function which logs what data is being added into "value" onclick, if I click a card, the console log the value of that specific card:
What I'm trying to do now is use this information in another component called ServiceForm. I want to be able to click the button, be linked to ServiceForm, and use the variables within "Item" in the ServiceForm component, Ideally as shown below;
<Form.Group as={Col} controlId="formGridForeName">
<Form.Label>**{item.description}**</Form.Label>
<Form.Control
name="firstName"
placeholder="Enter name"
onChange={this.handleChange}
/>
</Form.Group>
EventCard if a functionalComponent and ServiceForm is a class based component, how could I pass the information from the first to the latter? Thanks
Edit: To show component hierarchy
ServiceForm is rendered in ServiceApplication, as shown:
import * as React from "react";
import { ServiceForm } from "../components/ServiceForm";
class ServiceApplication extends React.Component {
render() {
return (
<React.Fragment>
<h1>Service Application</h1>
<h6>Users can use this page to apply for tickets.</h6>
<ServiceForm />
</React.Fragment>
);
}
}
export default ServiceApplication;
EventCard component is rendered in EventsPage, as shown below;
import EventCard from "../components/EventCards/EventCard";
class EventsPage extends React.Component {
render() {
return (
<React.Fragment>
<h1>Events</h1>
<h6>
Welcome to the Events, here you can apply for seats or tickets at the
events shown below.
</h6>
<Row>
<EventCard />
</Row>
</React.Fragment>
);
}
}
export default EventsPage;
The idea is to pass on the ID when Clicking the 'Tickets' button on the EventCard (the ID is being pulled from an API and mapped).
It's a question of how you want to store state in your app really.
Take a simple example where a component which is a child of another. In that case, the parent can store the state locally e.g. useState() and pass it down as props to the child.
const SomeParent = () => {
const [isTrue, setIsTrue] = React.useState(true)
return (
<Child isTrue={isTrue} />
)
}
There may be cases where you want to share state across multiple components, or across your whole app. In that case, you have a load of different options.
1. Lifting state up to the highest point you need.
It would be easiest to move your state which is shared between multiple components up to the highest point that the two components share.
e.g.
Section component <- store state here
Parent one
child one
child two
Parent two
child one
Here you can again either useState() or alternatively store the state in a useReducer() and pass dispatch down.
The data flow would then look something like this:
initialise state in the section component e.g. const [someState, setSomeState]
pass the setSomeState callback down to the Parent component and in turn child component as a prop e.g.
In the child component set state onClick using the callback e.g. onClick = {() => action(item)}
pass the state value down to your second Parent component and in turn child component e.g.
You have access to the state in your form
This can be an object or multiple state values. As complexity increases, I tend to reach for useReducer().
2. Implementing useContext OR Redux in your application to create an application state accessible from any component (This is a much bigger explanation and there are lots of resources on each...
NOTE: I'm not sure why you're using two sets of brackets here:
const handleClick = (value) => () => {
console.log(value);
};
and when you're calling handleClick you need to switch it for an arrow function if you're passing a value:
onClick={handleClick({ item })
...
onClick={() => handleClick(item)}
Try this:
const handleClick = (value) => {
console.log(value);
};
<Button variant="outlined" onClick={() => handleClick({ item })} />
basically, you want to trigger a class component function from a functional component by passing item prop, if it was a parent child components you can pass a function as a prop and trigger it whenever you want from your parent or child component.
but in your case both components are not connected, what you can do without using redux is to create a public local storage for ex let's call it localStorage.js :
var PublicData = (function() {
var data = null;
var getData = function() {
return data;
};
var setData = function(props) {
data = props;
};
var clearData = function() {
data = null;
};
return {
GET: getData,
SET: setData,
CLEAR: clearData
}
})();
export default PublicData;
then you import it and use like the following :
import PublicData from './PublicData.js';
PublicData.SET(apiData); // you set your data once you fetch it
const data = PublicData.GET(); // get data
PublicData.CLEAR(); // clear your data
Note : this is not an actual localStorage, but it work the same, it will help you to share variables between your components.
Parent
/ \
Service Event
I'm guessing from your question that a simplification of your app tree looks like the above.
The problem you are having is the following:
Parent
/ \
Service Event
Data
In a top down architecture Service does not know about Event and any data over there in the that branch.
So you have 2 options (likely more, but these 2 get you a long way):
Hoist the data
Parent
Data
/ \
Service Event
Store the data somewhere else and provide a mechanism for access
Data
Parent
/ \
Service Event
Option 1 can be achieved by passing props (the data) and functions (passed using props) to manipulate the data (or, indeed, populate it in the first place i.e. fetch it)
The flow would look something like:
Parent is stateful. Parent passes the current state of the data to children that care about it (in your case that looks like Service and Event). Parent passes a function to Event, which can be attached to a click handler within the Event subtree of elements.
Due to passing a function down, when that click handler is invoked it can set the state of the Parent, from which the normal top-down rendering flow will handle setting updates and passing the data changes down the tree, whereby they will (usually) invoke a re-render.
I think Recoil uses this method, and it is becoming increasing popular once more as we look to split applications up and eschew global state management.
Option 2 is where data management libraries like Redux, Cerebral, MobX et al live. If you’re familiar with the publisher/subscriber pattern then you'll know how they work.
In essence, these libraries hold shared state for your application, such as the data you have here. They then (typically) provide a pattern for you to manage changes to the state (via a published event) and ensure that components that subscribe to that data receive the new state and update.
The 'discussion' here differs from option 1:
The click handler publishes an event, which, in essence, asks for some manipulation to the data. Manipulation occurs (or not), and subscribers are updated. In your case, the click would tell the centralised store/s (i.e. anything listening) to fetch the data, when it is done and the data is changed (from empty to filled) it lets all concerned elements (or, quite possibly, the entire application tree and leverage top-down rendering) know about it and they can do what they need to do.
Which option you pick is entirely up to you, they both have pros and cons.
Good luck thinking about your data, how you store it, and how you use it!
I'm glad you asked this question because this is a problem that has been faced and solved a lot of the times. Other contributors have written nice comprehensive answers so I'll keep it short.
1. Move shared stated to a common ancestor.
This one's pretty straight forward but gets very hairy very quickly.
2. Use Context API
You can use react's context API to move code responsible for fetching data to your context and use that data anywhere in your app without a lot of hassle. This approach is getting quite popular nowadays. Take a look at this and here's a sweet library to help you get started.
3. Use a state management library (preferred)
You can choose to use any state management library you like to solve this problem. There are quite a few options, and redux is the most popular one and for a very good reason. It enables you in implementing separation for concern between your data and your UI, but is a bit verbose.
Mobx is also popular and has a good developer experience but I personally don't like that it enforces a certain style to your code.
If you're new to react and state management then these libraries could be really daunting. I'd suggest you start with zustand. It's super simple and gets the job done. ;)
You can simply use Custom Event https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent. It is not the best practice but it work.In EventCard, when user click you dispatch a Custom event with payload is item, then ServiceForm will listener that event and store item as state. Working demo here
https://codesandbox.io/s/distracted-aryabhata-ec6gc
EventCard
const handleClick = () => {
const item = {
description: "This is description"
};
const event = new CustomEvent("customEvent", {
detail: item
});
window.dispatchEvent(event);
};
Service Form
const [item, setItem] = useState(null);
...
useEffect(() => {
const handler = (e) => {
setItem(e.detail);
};
window.addEventListener("customEvent", handler);
return () => window.removeEventListener("customEvent", handler);
}, []);

Global variables in arrow function components

I am new to REACT so please correct me if I am wrong. When defining hooks, I can use the property all over my arrow function. Something like:
const CrawlJobs = () => {
const [crawlList, setCrawlList] = useState([]);
};
Everything OK here. As far as I understand the hooks in REACT is used because the render content know when data has changed and can update the DOM. But what if I have some simple properties/variables that is not used in the UI. Should I still define global variables as hooks? I tried defining a variable like this:
const statusId = 0;
However this could not be used globally in my arrow function component and doing below gave an error:
const this.statusId = 0;
So my question is should I always define all properties as hooks, or is there away to just define variables as standard variables in REACT? I dont want to define hooks if it is not needed.
You don't need to make a function to use useState so the correction:
const [crawlList, setCrawlList] = useState([]);
And functional component don't need this
You don't need to define your variables in the state as long as they are not affecting the application UI, component state usually used to notify the UI that there is a state it cares about changed, then the component itself should react to the change based on the state. the following is a silly example, just to demonstrate:
import React, { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
const label = 'You clicked';
return (
<div>
<p>{label} {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
So its totally fine to have variables without binding them to state.

Set initial state for material ui dialog

I have a MaterialUI dialog that has a few text fields, drop downs, and other things on it. Some of these elements need to be set to some value every time the dialog opens or re-opens. Others elements cannot be loaded until certain conditions exist (for example, user data is loaded).
For the 'resetting', I'm using the onEnter function. But the onEnter function doesn't run until entering (duh!)... but the render function, itself, still does - meaning any logic or accessing javascript variables in the JSX will still occur. This leaves the 'onEnter' function ill-equipped to be the place I set up and initialize my dialog.
I also can't use the constructor for setting/resetting this initial state, as the data I need to construct the state might not be available at the time the constructor loads (upon app starting up). Now, I could super-complicate my JSX in my render function and make conditionals for every data point... but that's a lot of overhead for something that gets re-rendered every time the app changes anything. (the material UI dialogs appear run the entire render function even when the 'open' parameter is set to false).
What is the best way to deal with initializing values for a material ui dialog?
Here is a super-dumbed-down example (in real life, imagine getInitialState is a much more complex, slow, and potentially async/network, function) - let's pretend that the user object is not available at app inception and is actually some data pulled or entered long after the app has started. This code fails because "user" is undefined on the first render (which occurs BEFORE the onEnter runs).
constructor(props) {
super(props);
}
getInitialState = () => {
return {
user: {username: "John Doe"}
}
}
onEnter = () => {
this.setState(this.getInitialState())
}
render() {
const { dialogVisibility } = this.props;
return (
<Dialog open={dialogVisibility} onEnter={this.onEnter}>
<DialogTitle>
Hi, {this.state.user.username}
</DialogTitle>
</Dialog> );
}
My first instinct was to put in an "isInitialized" variable in state and only let the render return the Dialog if "isInitialized" is true, like so:
constructor(props) {
super(props);
this.state = {
isInitialized: false
};
}
getInitialState = () => {
return {
user: {username: "John Doe"}
}
}
onEnter = () => {
this.setState(this.getInitialState(),
() => this.setState({isInitialized:true})
);
}
render() {
const { dialogVisibility } = this.props;
if(!this.state.isInitialized) {
return null;
}
return (
<Dialog open={dialogVisibility} onEnter={this.onEnter}>
<DialogTitle>
Hi, {this.state.user.username}
</DialogTitle>
</Dialog> );
}
As I'm sure you are aware... this didn't work, as we never return the Dialog in order to fire the onEnter event that, in turn, fires the onEnter function and actually initializes the data. I tried changing the !this.state.inInitialized conditional to this:
if(!this.state.isInitialized) {
this.onEnter();
return null;
}
and that works... but it's gives me a run-time warning: Warning: Cannot update during an existing state transition (such as withinrender). Render methods should be a pure function of props and state.
That brought me to a lot of reading, specifically, this question: Calling setState in render is not avoidable which has really driven home that I shouldn't be just ignoring this warning. Further, this method results in all the logic contained in the return JSX to still occur... even when the dialog isn't "open". Add a bunch of complex dialogs and it kills performance.
Surely there is a 'correct' way to do this. Help? Thoughts?
What you need conceptually is that when you are freshly opening the dialog, you want to reset some items. So you want to be able to listen for when the value of open changes from false to true.
For hooks, the react guide provides an example for keeping the "old" value of a given item with a usePrevious hook. It is then simply a matter of using useEffect.
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
function MyDialog({ dialogVisibility }) {
const prevVisibility = usePrevious(dialogVisibility);
useEffect(() => {
// If it is now open, but was previously not open
if (dialogVisibility && !prevVisibility) {
// Reset items here
}
}, [dialogVisibility, prevVisibility]);
return <Dialog open={dialogVisibility}></Dialog>;
}
The same thing can be achieved with classes if you use componentDidUpdate and the previousProps parameter it receives.
export class MyDialog extends Component {
public componentDidUpdate({ dialogVisibility : prevVisibility }) {
const { dialogVisibility } = this.props;
if (dialogVisibility && !prevVisibility) {
// Reset state here
}
}
public render() {
const { dialogVisibility } = this.props;
return <Dialog open={dialogVisibility}></Dialog>;
}
}
You should use componentDidUpdate()
This method is not called for the initial render
Use this as an opportunity to operate on the DOM when the component has been updated
If you need data preloaded before the dialog is opened, you can use componentDidMount():
is invoked immediately after a component is mounted (inserted into the tree)
if you need to load data from a remote endpoint, this is a good place to instantiate the network request
React guys added the useEffect hook exactly for cases like the one you are describing, but you would need to refactor to a functional component.
Source: https://reactjs.org/docs/hooks-effect.html
This can be solved by doing leaving the constructor, getInitialState, and onEnter functions as written and making the following addition of a ternary conditional in the render function :
render() {
const { dialogVisibility } = this.props;
return (
<Dialog open={dialogVisibility} onEnter={this.onEnter}>
{this.state.isInitialized && dialogVisibility ?
<DialogTitle>
Hi, {this.state.user.username}
</DialogTitle> : 'Dialog Not Initialized'}
</Dialog> );
)}
It actually allows the dialog to use it's "onEnter" appropriately, get the right transitions, and avoid running any extended complex logic in the JSX when rendering while not visible. It also doesn't require a refactor or added programming complexity.
...But, I admit, it feels super 'wrong'.

Categories