CSSTransition not showing transitions in React - reactjs

Here's my slideshow.jsx file.I am trying to apply transition to a sample div containing Sample Text,but no transitions happening.
import React, { Component } from 'react';<br>
import styles from '../stylesheets/style.module.css';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
class SlideShow extends Component {
state = {
backgroundColor: 'white',
changePic: true,
slideIndex: 1,
};
render() {
console.log(this.state.changePic);
return (
<div className={styles.slideshowContainer}>
<CSSTransition
in={this.state.changePic}
timeout={2000}
classNames={styles.slidePics}
mountOnEnter={true}
>
<div>
<p>sample text</p>
</div>
</CSSTransition>
</div>
);
}
}
export default SlideShow;
Here is my style.module.css file.Following properties associated with slidePics are below.But these transitions are not working:-
.slidePics-enter {
opacity: 0;
}
.slidePics-enter-active {
opacity: 1;
transition: opacity 2000ms;
}

the issue is you dont have a class slidePics at your css modules to be mapped to styles. if you add an empty rule .slidePics { } solves the issue.
other viable approach, you could map your transictions as:
classNames={{
enter: styles['slidePics-enter'],
enterActive: styles['slidePics-enter-active'],
}}
update
you already have in prop as true, given initial state. in initial state needs to be false and then with some iteraction you would change to true with the classes enter enter-active.
by your code, you would like to perform transition on mount state but as the docs says css transition wont perform enter transition by default on first mount.
for that to happen, you need to pass appear={true} and in={true}. likewise create the classes .slidePics-appear .slidePics-appear-active like you have for enter classes.

Related

CSSTransition:- React.Children.only expected to receive a single React element child

Below in my code. CSSTransition is not being recognized. It throws an error for some reason. I tried importing with and without braces, but it didn't seem to work.
import React, { Component } from 'react';
import styles from '../stylesheets/style.module.css';
import { CSSTransition } from 'react-transition-group';
class SlideShow extends Component {
state = {
backgroundColor: 'white',
changePic: true,
slideIndex: 1,
};
render() {
return (
<div className={styles.slideshowContainer}>
<CSSTransition
in={this.state.changePic}
timeout={{
enter: 2000,
exit: 800,
}}
classNames="slidePics"
unmountOnExit={true}
></CSSTransition>
</div>
);
}
}
export default SlideShow;
Two things:
Make sure to actually install react-transition-group
Import without curly braces

Locate a component in React project

I wrote a Logout button component in my React app for which I wish to locate at the top right corner of the screen.
render() {
<LogoutButtonComponent height: , backgroudColor: />
}
It wouldn't let me assign any values for height and etc.
This is the Logout component:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return <button type="button" onClick={this.handleClick}>Logout</button>;
}
}
Should I locate it by < col /> ?
To add inline styles, you should defined a style object as prop, and pass it values, like doniyor2109 mentioned. There are a few caveats to using this, however.
style={{ height: 100, height: '100px', height: '100%', minHeight: '100px'}}.
Not every value should be passed as integer, some need to be passed as a string
Not every css attribute gets passed as you would expect them to, the css min-height actually gets passed as minHeight, so replace all hyphens with lower camel case style
Inline styles get insanely difficult to manage. I suggest you at the very least create an object outside the component, and pass it in like:
const DivStyle = { minHeight: '100px' }
and then:
<LogoutButtonComponent style={DivStyle} />
You can prefix that DivStyle with an export if you want to import {DivStyle} from './somefile' in other places
I suggest you check out a library like styled-components as it makes styling much easier!
I suggest you check out this article which outlines your options
You don't really add styles to your component like that. It's better to add those styles in the source for the actual component. So how exactly do you want it displayed? I will provide a template kind of and you can change it to what you want.
Go to your source for your Logout Button Component. In the return of your render method try adding a div call it container. Then add styling in a css file to that div or if you are using react-bootstrap or reactstrap or #material/ui/core you can adjust the style according to their documentation.
You can add your css for the className .container to make it appear the way you would like.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class LogOutButton extends Component {
static contextTypes = {
store: PropTypes.object.isRequired,
};
handleClick = () => {
this.props.onLogout();
};
render() {
return (
<div className="container">
{* notice the className here *}
<button type="button" onClick={this.handleClick}>Logout</button>
</div>
)
}
}
Hope this helps.

React Transition Group And Animations

The problem is I have a form whit three states: default, error and success. Depending on the state, a specific component is rendered into the dom.
I need to add a fade in out animation when this component enters or leave.
I've tried whith custom CSS, GSAP ( but don't want to install more packages to my project ) and now trying with react-transition-group.
To keep is simple I've created the "error" component as follow:
export default class NewsletterFormError extends React.Component {
componentWillMount() {
}
componentDidMount() {
}
render() {
return (
<div className="NewsletterFormError">
I'm an error message
<style jsx>{`
.NewsletterFormError {
font-size: 50px;
}
`}</style>
</div>
)
}
}
And on the index page I have:
{ this.state.formError &&
<CSSTransitionGroup
transitionName="test"
transitionAppear={true}
transitionAppearTimeout={200}
transitionEnter={true}
transitionEnterTimeout={2000}
transitionLeave={true}
transitionLeaveTimeout={2000}>
<NewsletterFormError />
</CSSTransitionGroup>
}
For some reson, when this.state.formError is true, the component renders and the fade in is done, but when the state chages to false, the fade out is not working.
Unfortunately, pure React CSS Transition groups can't trigger an animation when a component is unmounted. See this github issue for more details. This repo with a comparison of animation methods in react may be helpful, they recommend using React CSS Transition groups in conjunction with GSAP or Anime.js

React props.children width

Is there anyway of getting the width of React component children. I have wrapper component called for lack of name Container and I add children of div type from Component1 to it. See below example.
I'm wondering if there is a way to get the width of each div child in Container when it mounts.
UPDATED NOTE:
The reason I'm trying to get the containers children widths is so I can dynamical set the containers width based on the total number of children. By setting the containers width to the number of children's width then I can allow for some horizontal scrolling effects I want to do.
Component 1
export default class Component1 extends Component{
render(){
return(
<Container>
<div className="large-box"/>
<div className="large-box-dark"/>
</Container>
)
}
}
Now my Container component.
export default class Container extends Component{
componentDidMount(){
this.props.children.forEach(( el ) => {
// get each child's width
console.log("el =", el);
});
}
render() {
return (
<div className="scroller" ref={(scroller) => { this.scroller = scroller }}>
{this.props.children}
</div>
)
}
}
You can use refs. Although you should avoid touching the DOM until and unless there is no other way. But here we go.
Give your child components a ref which is escape hatch provided by React to access the DOM(with a warning to use other methods before coming to this).
Child Component
class ChildComp extends Component {
getWidth = () => {
//Access the node here and get the width
return this.childNode.offsetWidth(); //or clientWidth();
}
render() {
return (
<div ref={(r) => {this.childNode = r}}>
</div>
);
}
}
Parent Component:
class ParentComp extends Component {
componentDidMount() {
//Access the child component function from here
this.childComponent.getWidth();
}
render() {
return (
<ChildComp
ref={(r) => {this.childComponent = r}} />
);
}
}
But do remember use the above method when there is no way of getting the thing done declaratively.
I would say that technically it doesn't seem possible. The JSX
<div className="large-box"/>
does not refer to DOM element, (which has a width once it's been rendered) but to a React element, which is an in-memory object describing how to make an DOM element. Since the React element isn't rendered or even connected to the actual DOM in the browser, it can't know the width.
Remember that React can be rendered on the server -- there's no way the server can know what the browser on different computer is going to display.
I'd also echo what Pedro Nascimento noted -- this solution is probably best solved some other way, but without context, it's difficult to help.
then try to get the ref of "DivColorOpacy"! and put whatever you want on parent and cutom your behavior. That's silly but that do the job.
with this css
.DivColorOpacy{
height: max-content;
width: max-content;
position: relative;
}
import { Component } from "react";
import * as React from "react";
interface DivColorOpacyProps {
backgroundColor: string,
opacity: number,
}
export class DivColorOpacy extends Component<DivColorOpacyProps, any>{
componentDidMount(){
}
render() {
const { backgroundColor, opacity } = this.props;
return <div className="DivColorOpacy">
{this.props.children}
<div style={{
position: "absolute",
zIndex: -1,
backgroundColor,
opacity,
width: "100%",
height: "100%",
top:0
}} />
</div>
}
}

size element based on another element's dimensions in reactjs

Say I have an element like this:
export default class DemoAxis extends Component {
componentDidMount() {
const el = findDOMNode(this);
this.dimensions = getDimensionsFromNode(el);
}
render() {
const style = {
parent: {border: "1px solid #ccc", margin: "2%", maxWidth: "40%", padding: 10}
};
return (
<div ref="line">
<svg style={style} width={this.dimensions.width} height={this.dimensions.height}
I want to size the svg element based on the dimensions of the line element.
The element's dimensions will only be available in componentDidMount which is called after render.
I know I can call setState but that will cause a re-render and that might give me UI issues.
What is the best way of achieving this?
You can try react-dimensions
Wraps a react component and adds properties containerHeight and containerWidth. Useful for responsive design. Properties update on window resize. Note that the parent element must have either a height or a width, or nothing will be rendered
// ES2015
import React from 'react'
import Dimensions from 'react-dimensions'
class MyComponent extends React.Component {
render() (
<div
containerWidth={this.props.containerWidth}
containerHeight={this.props.containerHeight}
>
</div>
)
}
export default Dimensions()(MyComponent) // Enhanced component

Resources