Hide or show div element - reactjs

I would like to find out how you can hide and show div element in react typescript. This is the code that I have so far. Any feedbacks
function GetUserInfo (user:User)
{
let userInfo = USERINFO.find((d) => d.Address === user.Address);
if(userInfo)
{
//Show Div
showDiv
}
return userInfo.data
}
function showDiv(props) {
return <div id="missingPO">Unable at identify user info.</div>
}

The code you have written is a bit unclear about how you wanna hide it,
But for example, you want to hide an element in case a variable is true, in your case can be something with an address or what you are trying to do.
for example, I want to hide a value when const isHidden=true
I will discuss two ways.
You can declare a class that hides the div, for example in your global class add a CSS class
.hidden{
display: none;
}
then in your div, you can check if isHidden enables class.
<div className={isHidden && 'hidden'} />
you can check like this
//in your method return div in case you are not hidden, pass the isHidden as props.
function showDiv(props) {
return props.isHidden ?<></>: <div id="missingPO">Unable at identify user info</div>
}
// or just check with &&
!isHidden && <div> will show only if is hidden false</div>
// the pros of using the second one are because you are unmounting div, but this can be a downside too, depends what you need
// with display it will remove from the page, but now from the dom, also you can make visibility: hidden if you do not want to remove it from the page just to hide.
If you have any question please ask 😄

Related

How to return two JSX elements in React to be rendered in different places?

Say I have a sub component responsible for handling some user input
function MyInputComponent(props: {...}) {
return <input>...</input>;
}
Now say I want to add a button to control that input, normally I would do:
function MyInputComponent(props: {...}) {
return <>
<input>...</input>
<button>...</button>
</>;
}
This works so far. But now I want to render the button at some other places (i.e. not within the same component). e.g. if we look at the final html, I want to have the button to be after another component:
<parent-component>
<input>...</input>
<some-other-component>...</some-other-component>
<button>...</button>
</parent-component>
Of course, one way is to pass in <some-other-component> to MyInputComponent for it to render, but I want that code separation as MyInputComponent has nothing to do with that other component. And I don't want the parent component to handle the parameters for the <button> either as all the control logic (e.g. onClick action, etc.) are local to MyInputComponent only.
Is there a way to return {<input>, <button>} to the parent component, so that it can render them at desire places?
Try to use array instead of fragment
const [MyFirstComponent, MySecondComponent] = () => {
return [
<h1>Element 1</h1>,
<span>Element 2</span>
];
}

React element events

So I'm trying to style an element when user focuses/hovers on an input/button. The way I'm doing it is by using a state and setting it to true or false if the user has hovered or focused but find it very repetitive and will take a lot of code, considering I would have to create a focused and hovered state for each button or input.
For example, I'm doing :
const [hoveredBtn, setHoveredBtn] = useState(false)
const [themecolor, setThemecolor]=useState('red') //this state is being from firebase, red would
//just be an example, it can be whatever the user sets it to.
return (
<button
onMouseOver={()=>setHoveredBtn(true)}
onMouseLeave={()=>setHoveredBtn(false)}
style={hoveredBtn?{backgroundColor: themecolor}:{backgroundColor:"white"}}
>
Button
</button>
)
Therefore, I would need to create a hovered variable for each button or input I have and im looking to know if there is a way to do it like this, but when I tried I get an error:
return (
<button onMouseOver={this.style.color=themecolor} onMouseLeave=
{this.style.color='white'}>Button</button>
)
You can’t specify pseudo-classes using inline styles. That means :hover, :focus, :active, or :visited go out the window rather than the component.
source: https://www.freecodecamp.org/news/react-styled-components-inline-styles-3-other-css-styling-approaches-with-examples/
style.css:
.myComponent:hover {
// define style
}
myReactComponent.jsx:
import './style.css';

Toggle property of different states

Small question here.
I have 3 div classes that contain images that I want to toggle the state property for each picture every time a user presses on one of the images (div actually).
The states are as follows:
constructor(props) {
super(props);
this.state = {
img_1: 0,
img_2: 0,
img_3: 0
};
}
And I want to have a single handle function that can toggle for all the different images that I have.
Here is the div code (its the same for every image):
<div className="pics" onClick={(e) => this.handlePic(e)}>
<h2>First picture</h2>
<img alt="" src={pic1} className="tier2"/>
</div>
And The handle function is empty at the moment, because I have no idea how to pass into it the name of this.state.img_1. The value of course should toggle between 0 and 1, but I want to be able to use a single function for the toggle of all 3 images.
I am not sure if my question makes a lot of sense, please let me know if you want me to explain a little bit more of my situation.
Thank you!
You have 3 different div, in each of your dives define an onClick={()=>this.myhandle(nameofpic)} (you can hardcode nameofpic here,for example in each div put a name like "img1","img2" ... instead of nameofpic)
Then in your myhandle() put your ifs ,like this :
myhandle(nameofpic){
if(nameofpic==="img_1")
{this.setState({img_1:"valuechange"})
}
if(nameofpic==="img_2")
{this.setState({img_2:"valuechange"})
}
if(nameofpic==="img_3")
{this.setState({img_3:"valuechange"})
}}
I hope you get the idea and works for you
You should create a separate component for Image, which will handle it's own state. This way you can manage any number of Images not just 3.
function Image({url}) {
const [overlay, setOverlay] = useState(false);
const toggleState = () => {
setOverlay(!overlay)
}
return <img src={url} alt={url} onClick={toggleState} />
}
Here overlay can be anything.
Now you can use this component any number of time and it will have it's own state management.
Here is the solution if you are not using hooks then,
In render method(passing static string in parameter for handler method):
<div className="pics" onClick={e => this.handlePic('img1')}>
<h2>First picture</h2>
<img alt="" src={pic1} className="tier2" />
</div>
Your handler(Setting dynamic key):
handlePic = key => {
this.setState(prevState => ({ [key]: !prevState[key] })); // This will toggle 0 or 1 simultaneously.
};

React- onClick styling of currentTarget

I am trying to build a simple dynamically updated, interactive list that styles each <li></li> according to the css rules of a .clicked class, when you click on them.
The app is composed of two components, a parent and a child and the code in question is the following (taken from the child):
handleClick(e) {
document.getElementById(e.currentTarget.id).setAttribute("class","clicked");
}
render() {
let ar = this.props.sentences;
let pro = ar.map((x,i)=>{ return (<li id={i} key={i} className={i%2==0 ? "white" : "grey"}
onClick={this.handleClick}>{x}</li>); })
return (
<div>
<ul id="ul">{ pro }</ul>
</div>
What is happening here is basically that the parent is passing to the child a sentences prop (an array of sentences that will form the basis for the formation of a dynamic list).
The controversial part is me using DOM manipulation in the form of document.getElementById(e.currentTarget.id).setAttribute("class","two");
in order to change the class of the dynamically created html from jsx.
The code above works, however it does not feel as best practice. The whole advantage in using react is to use virtual dom and optimize the way the DOM is updated.
My questions are the following:
1) Am I right to feel this way? (that my solution is not best practice?)
2) (If so, ) How can I structure my code in order to use the virtual dom machinery react offers?
If you know this question to be a duplicate, please leave a comment and I ll remove it.
1) Am I right to feel this way? (that my solution is not best practice?)
It is correct to assume that this is not an ideal approach, manipulating the DOM via vanilla js in React has its place (Example Use Cases) but should not be done unless absolutely necessary. Also, it is not ideal to use the index from Array.prototype.map as the key on your components as if they change order it can cause confusion for React as the keys would map differently in that case.
2) (If so, ) How can I structure my code in order to use the virtual dom machinery react offers?
You should make use of the component state. If you want each clicked element to maintain the clicked class then make a piece of state that caches the elements that have already recieved the clicked class. if only the most recently clicked element gets the clicked class then simply cache an identifier to the appropriate element in the state. You could also use refs for this purpose though the overusage of them is somewhat discouraged by facebook.
Here is a quick snipped that will toggle the click class on each <li>
class Test extends Component {
constructor() {
super();
this.state = {
clicked: {}
};
}
render() {
let ar = this.props.sentences;
let pro = ar.map((x, i) => {
const color_class = i % 2 === 0 ? "white" : "grey";
const clicked_class = this.state.clicked[i] === true ? "clicked" : "";
let clicked = Object.assign({}, this.state.clicked); // Dont mutate state!!!
return (
<li
id={i}
key={i}
className={`${color_class} ${clicked_class}`}
onClick={e => {
if (clicked.hasOwnProperty(i)) {
delete clicked[i];
} else {
clicked[i] = true;
}
this.setState({ clicked });
}}
>
{x}
</li>
);
});
return (
<div>
<ul id="ul">
{pro}
</ul>
</div>
);
}
}

How to wait and fade an element out?

I have an alert box to confirm that the user has successfully subscribed:
<div className="alert alert-success">
<strong>Success!</strong> Thank you for subscribing!
</div>
When a user sends an email, I'm changing the "subscribed" state to true.
What I want is to:
Show the alert box when the subscribed state is true
Wait for 2 seconds
Make it fade out
How can I do this?
May 2021 update: as tolga and Alexey Nikonov correctly noted in their answers, it’s possible to give away control over how long the alert is being shown (in the original question, 2 seconds) to the transition-delay property and a smart component state management based on the transitionend DOM event. Also, hooks are these days recommended to handle component’s internal state, not setState. So I updated my answer a bit:
function App(props) {
const [isShowingAlert, setShowingAlert] = React.useState(false);
return (
<div>
<div
className={`alert alert-success ${isShowingAlert ? 'alert-shown' : 'alert-hidden'}`}
onTransitionEnd={() => setShowingAlert(false)}
>
<strong>Success!</strong> Thank you for subscribing!
</div>
<button onClick={() => setShowingAlert(true)}>
Show alert
</button>
(and other children)
</div>
);
}
The delay is then specified in the alert-hidden class in CSS:
.alert-hidden {
opacity: 0;
transition: all 250ms linear 2s; // <- the last value defines transition-delay
}
The actual change of isShowingAlert is, in fact, near-instant: from false to true, then immediately from true to false. But because the transition to opacity: 0 is delayed by 2 seconds, the user sees the message for this duration.
Feel free to play around with Codepen with this example.
Since React renders data into DOM, you need to keep a variable that first has one value, and then another, so that the message is first shown and then hidden. You could remove the DOM element directly with jQuery's fadeOut, but manipulating DOM can cause problems.
So, the idea is, you have a certain property that can have one of two values. The closest implementation is a boolean. Since a message box is always in DOM, it's a child of some element. In React, an element is result of rendering a component, and so when you render a component, it can have as many children as you want. So you could add a message box to it.
Next, this component has to have a certain property that you can easily change and be completely sure that, as soon as you change it, the component gets re-rendered with new data. It's component state!
class App extends React.Component {
constructor() {
super();
this.state = {
showingAlert: false
};
}
handleClickShowAlert() {
this.setState({
showingAlert: true
});
setTimeout(() => {
this.setState({
showingAlert: false
});
}, 2000);
}
render() {
return (
<div>
<div className={`alert alert-success ${this.state.showingAlert ? 'alert-shown' : 'alert-hidden'}`}>
<strong>Success!</strong> Thank you for subscribing!
</div>
<button onClick={this.handleClickShowAlert.bind(this)}>
Show alert
</button>
(and other children)
</div>
);
}
}
Here, you can see that, for message box, either alert-shown or alert-hidden classname is set, depending on the value (truthiness) of showingAlert property of component state. You can then use transition CSS property to make hiding/showing appearance smooth.
So, instead of waiting for the user to click button to show the message box, you need to update component state on a certain event, obviously.
That should be good to start with. Next, try to play around with CSS transitions, display and height CSS properties of the message box, to see how it behaves and if the smooth transition happening in these cases.
Good luck!
PS. See a Codepen for that.
The correct way is to use Transition handler for Fade-in/out
In ReactJS there is synthetic event to wait till fade-out is finished: onTransitionEnd.
NOTE there are different css effects associated with different handlers. Fade is a Transition not an Animation effect.
Here is my example:
const Backdrop = () => {
const {isDropped, hideIt} = useContext(BackdropContext);
const [isShown, setState] = useState(true);
const removeItFromDOM = () => {
debugger
setState(false)
};
return isShown
? <div className={`modal-backdrop ${isDropped ? 'show' : ''} fade` } onClick={hideIt} onTransitionEnd={removeItFromDOM}/>
: null
}
An other way is to solve this with a CSS3 transition.
https://www.tutorialspoint.com/css/css_animation_fade_out.htm
You can add a new class to the alert (like .hidden) and then you can relate .hidden with the class you defined for the alert.
alert.hidden{
// Here you can define a css transition
}
In this solution you don't have to add a setInterval or anything, since css3 transitions already process it on browser render.

Resources