How to fade text in, then out - reactjs

I'm trying to make a notification next appear to a text input to inform the users their text was saved, and then fade that notification text out.
Basically I'm trying to replicate this action, when a corresponding text input is submitted.
$(this).fadeOut().next().fadeIn();
I can't think of any way to fade it in, then out, that isn't absurdly roundabout.
I'm using Redux as well, and would like to use that, but it's not a requirement. Any advice would be appreciated.

You can use CSS to take care of that. Here's a very simple example (not using redux). Use JS to trigger, CSS to style.
class App extends React.Component {
constructor() {
super();
this.state = {
show: false
};
this.showNotification = this.showNotification.bind(this);
}
showNotification() {
// You can use redux for this.
this.setState({
show: true,
});
setTimeout(() => {
this.setState({
show: false,
});
}, 1000);
}
render() {
return (
<div>
<button onClick={this.showNotification}>Save</button>
<Notification show={this.state.show} />
</div>
);
}
}
class Notification extends React.Component {
render() {
return <span className={this.props.show ? 'show' : ''}>Saved!</span>
}
}
ReactDOM.render(<App/>, document.getElementById('View'));
span {
transition: 300ms all ease;
opacity: 0;
will-change: opacity;
}
.show {
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="View"></div>

i know react is really great and all but lets not forget about jquery:
this is a little bit less absurdly round about:
$('#mydiv').fadeOut(3000)

Related

Using STATE as html ATTR in React JSX

I am working in ReactJS, and have a URL of a photo stored in State. I want to use that photoURL to call up the image in my component render. But it when I use the normal src={this.state.photoURL} it throws an error.
Ideally, I would be able to use it as a background image in a container like this:
<div className='photo-cont' style='background-image:url({this.state.photoURL}); background-size:cover;'
I've tried this and as a normal img, with and without quotes around the curly braces, with and without the curly braces themselves.
class Foo extends Component {
state: {
photoURL: 'www.foobar.com/foo.jpg',
}
render () {
return(
<img src={this.state.photoURL}></img>
)
}
}
I keep getting the following error: 'TypeError: Cannot read property 'photoURL' of null'
It seems like you have a typo in your code. To initialize a class field (like state you should use =.
I added both an example of the photoURL as an image and as a background image of a div. Remember to set width/height/padding on the div to show the image:
class Foo extends React.Component {
state = {
photoURL: 'https://unsplash.it/400/200',
}
render () {
return(
<div>
<img src={this.state.photoURL}/>
<div style={{
width: '400px',
height: '200px',
backgroundImage: `url(${this.state.photoURL})`,
}}/>
</div>
)
}
}
ReactDOM.render(<Foo/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
class Foo extends Component {
contructor(props) {
super(props)
this.state = {
photoURL: 'www.foobar.com/foo.jpg',
}
}
render () {
return(
<img src={this.state.photoURL}></img>
)
}
}
try to use contructor() to defined your state
import logo from './logo.png';
class Foo extends Component {
render () {
return(
<img src={logo}></img>
)
}
}
Check out their documentation:
https://facebook.github.io/create-react-app/docs/adding-images-fonts-and-files

Change element content with onClick in React

In my application I have multiple blocks generated dynamically and each one of them has an onClick event.
My goal is to be able to change the contents of the div when the click happens.
Is there a way to do this thru event.target property of the onClick event?
Or should i create a ref for each div upon creation and then work with refs?
Or should i create an array of Div elements in component state and search&modify the element later re-rendering all divs from array?
Since blocks are generating dynamically, have onClick event on children components.
const Parent = () => {
return (
<Child content={content} contentAfterClick={content} />
<Child content={content} contentAfterClick={content} />
)
}
class Child extends Component {
constructor() {
super();
this.state ={
read: false,
};
}
render() {
if (this.state.read) {
return(
<div>{this.props.contentAfterClick}</div>
)
}
return (
<div onClick={() => this.setState({ read: true })}>
<div>{this.props.content}</div>
</div>
);
};
}
This demo illustrates how you can change the contents of a div, the text, when a click happens through the onClick and event.target object as you wanted.
You can do this through the use of refs, but normally you want to avoid refs unless absolutely necessary because there are easier ways to accomplish the same thing in React.
Also wouldn't want to keep the physical DOM nodes, HTMLDivElement, in state. Instead, keep the contents it relies upon in state (in our case a single number value), then when you change the contents it will automatically update and rerender our div nodes.
// Example class component
class Container extends React.Component {
constructor(props) {
super(props);
const blocks = [];
blocks.push(0);
blocks.push(0);
blocks.push(0);
this.state = { blocks: blocks, clickedElementContents: "" };
}
increment(event, index) {
const newBlocks = this.state.blocks;
newBlocks[index]++;
this.setState({ blocks: newBlocks, clickedElementContents: event.target.innerText });
}
render() {
return (
<div>
<div className="block" onClick={(event) => { this.increment(event, 0) }}>Click me! ({this.state.blocks[0]})</div>
<div className="block" onClick={(event) => { this.increment(event, 1) }}>Click me! ({this.state.blocks[1]})</div>
<div className="block" onClick={(event) => { this.increment(event, 2) }}>Click me! ({this.state.blocks[2]})</div>
<span>Contents of the clicked element: {this.state.clickedElementContents}</span>
</div>
);
}
}
// Render it
ReactDOM.render(
<Container/>,
document.body
);
.block {
display: inline-block;
background-color: black;
color: white;
padding: 5px;
margin-right: 10px;
}
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

How to fill circle border based on progress in REACTJS

How to complete the border of circle based on selected option.
Here is four options.
1.Head
2.Body
3.Script
4.End Note
And I have a circle on side. What I am trying to do is, Head is by default active so circle border should be red color till 25% of its total area, then after selection of body it should be 50%. So on and at the end it should 100%.
Here is my code which I tried on click its changing text color till 4 clicks but I want above kind of thing.Being beginner in ReactJS I am unable to get this logic.
import React, { Component } from "react";
export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
title: "Click here",
color:"red",
active:false,
clicks: 0,
}
}
getInitialState() {
return {
count: 0
};
}
changeTitle = () => {
this.setState((prevState) => ({
clicks: prevState.clicks + 1,
title: "New title",color:"green",active:true,
}));
};
render() {
return (
<div>
<div>count:{this.state.clicks}</div>
<h1 onClick={this.changeTitle.bind(this)} >Hello World </h1>
<h1 style={this.state.clicks===1 ? {color:"red"}:
(this.state.clicks===2)?{color:"yellow"}:
(this.state.clicks===2)?{color:"black"}:
{color:"green"}}>This is Magic: {this.state.title}</h1>;
</div>
)
}
}
Shoutout to #Ron for providing an answer in jquery (https://stackoverflow.com/a/50208291/7956790).
Use the css provided by #Ron.
Ok, here's the render function in React:
// your previous code
render() {
return (
<div id="circle-container">
<div className="quarter top-left">
<div className="quarter-fill top-left-fill" onClick={this.handleTopLeftClick}></div>
</div>
<div className="quarter top-right">
<div className="quarter-fill top-right-fill" onClick={this.handleTopRightClick}></div>
</div>
<div className="quarter bottom-left">
<div className="quarter-fill bottom-left-fill" onClick={this.handleBottomLeftClick}></div>
</div>
<div className="quarter bottom-right">
<div className="quarter-fill bottom-right-fill" onClick={this.handleBottomRightClick}></div>
</div>
</div>
);
}
Hook your onClick listeners to your arcs, e.g. onClick={this.handleTopRightClick} and bind them in the constructor function:
constructor(props) {
super(props);
this.handleTopLeftClick.bind(this);
this.handleTopRightClick.bind(this);
this.handleBottomLeftClick.bind(this);
this.handleBottomRightClick.bind(this);
}
And now define your handler functions in your class:
handleTopLeftClick() { }
handleTopRightClick() { }
handleBottomLeftClick() { }
handleBottomLeftClick() { }

reactjs resetting props for componentWillReceiveProps

First question from my first react project.
I'm trying to figure out how to best effect a component on a specific onClick link, to be able to retrigger this effect and to not have it effected by other links on the page. The first two asks are working, but I can't seem to have other links not effect the component.
I have a DisplayLightbox component on my page accepting a couple values
<div>
<DisplayLightbox
showLightbox = {this.state.showLightbox}
lightboxValue = {this.state.travelCity}
/>
</div>
The link I want to trigger the lightbox is calling a function that sets the state (and sends the prop). This part seems to work fine.
onClick={() => this.showLightbox(el.field_city)}
showLightbox(travelCity){
this.setState({
showLightbox: true,
travelCity: travelCity,
});
}
In my DisplayLightbox component, the componentWillReceiveProps does set state to true, which adds the lb-active class in the div, which, from the css, displays the lightbox div. This seems fine.
class DisplayLightbox extends React.Component {
constructor(props) {
super(props);
this.state = {
showLightbox: false,
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.showLightbox !== this.state.showLightbox) {
this.setState({ showLightbox: nextProps.showLightbox });
}
}
closeLightbox() {
this.setState({
showLightbox: false,
});
}
render() {
var lbActive = (this.state.showLightbox === true) ? "lb-active" : ""
return <div className={"lightbox " + lbActive }>
<div className={"lightbox-close " + lbActive } onClick={() =>
this.closeLightbox()}>CLOSE</div>
Copy in lightbox
</div>;
}
}
Looking into it, I see that since props are not controlled by the component and read-only, once it's set as True and I close the div by setting the state of showLighbox back to false, the nextProps.showLightbox remains true. So, if I close it (closeLightbox) and click a different onClick on my page, it still looks into my component, sees nextProps.showLightbox is still set to TRUE and opens the lightbox.
I only want the lightbox open if that specific link is the one being clicked though. It would seem overkill to have every other link setting the state of showLightbox to false, so I'm guessing I'm not looking at this properly.
Thanks
You could just move your closeLightbox method to upper component and manage showLightbox prop from parent. Then component DisplayLightbox will have 3 props: showLightbox, travelCity and method closeLightbox.
When you move closing lightbox to parent component, event componentWillReceiveProps should be no longer needed.
It would seem overkill to have every other link setting the state of
showLightbox to false, so I'm guessing I'm not looking at this
properly.
Why not configure only the one link you want to turn on / off the lightbox then?
As i see it, a component who gets its active state from the parent or external component, should not bother to manage it in its own state.
You can manage the on / off state in the parent's state and pass down a isOn and onClose event handler to the LightBox.
Once the LightBox was clicked it will invoke the handler passed down to it and the parent will change the state of isOn to false, this will trigger a render with a new prop of isOn for the LightBox this time it's value is false.
While clicking the external link / button the parent will listen to it and change the state of isOn to true, and again isOn will passed down to LightBox with it's shiny new value of true.
Small example:
const cities = ["ny", "tlv", "ark"];
class Button extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
const { item, onClick } = this.props;
onClick(item);
}
render() {
return <button onClick={this.onClick}>{this.props.children}</button>;
}
}
class LightBox extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick() {
const { city, onClick } = this.props;
onClick(city);
}
render() {
const { isOn } = this.props;
const css = `lightBoxStyle ${isOn && "onStyle"}`;
return (
<div
className={css}
onClick={this.onClick}>
|
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
turnedOn: []
};
this.on = this.on.bind(this);
this.off = this.off.bind(this);
}
on(city) {
const { turnedOn } = this.state;
if (turnedOn.find(c => c === city)) {
return;
}
const nextState = [...turnedOn, city];
this.setState({ turnedOn: nextState });
}
off(city) {
const nextState = this.state.turnedOn.filter(c => c !== city);
this.setState({ turnedOn: nextState });
}
render() {
const { turnedOn } = this.state;
return (
<div>
{cities.map((city, i) => {
const isOn = turnedOn && turnedOn.includes(city);
return (
<div style={{ display: "inline-block", margin: "0 10px" }}>
<LightBox city={city} isOn={isOn} onClick={this.on} />
<hr />
<Button item={city} onClick={this.off}>
Close the light!
</Button>
</div>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.lightBoxStyle{
border: 1px solid #eee;
width: 30px;
height: 30px;
text-align: center;
box-shadow: 0 0 4px 1px #222;
border-radius: 50%;
margin: 0 auto;
cursor: pointer;
}
.onStyle{
background-color: #333;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Based on the great replies, I took the close out of the child and back to the parent.
I did this by adding a lightbox-button div to the parent
<div className={"lightbox-button " + this.state.showLightbox} onClick={() => this.showLightbox()}></div>
<DisplayLightbox
showLightbox = {this.state.showLightbox}
lightboxValue = {this.state.travelCity} />
This calls the same function showLightbox, that I modified slightly to toggle
showLightbox(travelCity){
this.setState({
showLightbox: !this.state.showLightbox,
travelCity: travelCity,
});
}
Using css, I keep this lightbox-button hidden, unless this.state.showLightbox is true. When that happens, the button displays and, when click, toggles the showLightbox state, thereby removing the lightbox and button.
Not sure if this is the ideal solution, but it seems to be working.

In React, onMouseEnter or hover is not working as expected

I have one image with opacity = 1 at the beginning.
When mouse enters the image, change opacity = 0.5. When mouse leaves the image, change the opacity back.
here is one code:
mouseEnter() {
console.log('mouse enter')
const classname = '.' + this.props.post.code
document.querySelector(classname).classList.add('image-hover-opacity')
}
mouseLeave() {
console.log('mouse leave')
const classname = '.' + this.props.post.code
document.querySelector(classname).classList.remove('image-hover-opacity')
}
render() {
<img src={src} onMouseEnter={::this.mouseEnter} onMouseLeave={::this.mouseLeave} />
}
onMouseEnter and onMouseLeave are fired when mouse enters and leaves the image, respectively, good. But the problem is when I move the mouse inside the image, both onMouseEnter and onMouseLeave are fired.
And I have tried css solution as well, when I hover on image, change the opacity property. But the problem is the same: when I move mouse inside the image, :hover and not hover are fired multiple times.
How to solve this? thanks
UPDATE
There is something in my previous code. Created one jsfiddle, and it works.
sorry guys
Using document.querySelector is not a very React way of thinking. You can try this approach:
Use a div wrapping this img to avoid this weird mouseEnter behavior
Use this.state with opacity
constructor() {
this.state = {
opacity: 1
}
}
mouseEnter() {
console.log('mouse enter')
this.setState({opacity: 0.5})
}
mouseLeave() {
console.log('mouse leave')
this.setState({opacity: 1})
}
render() {
<div style={{opacity: this.state.opacity}}>
<img src={src} onMouseEnter={::this.mouseEnter} onMouseLeave={::this.mouseLeave} />
</div>
}
I really think you can achieve this in CSS only.
So your component should have simple className property and that class should have the definitions for:
.image-hover-opacity:hover {
opacity: 0.5;
}
class Example extends React.Component {
constructor() {
super();
this.state = {};
}
render() {
return(
<img className="image-hover-opacity" src="http://i.imgur.com/PLKabDV.png" />
);
}
}
ReactDOM.render(<Example />, document.getElementById('root'));
.image-hover-opacity:hover {
opacity: 0.5;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources