Giving React component animation on mount - reactjs

I am trying to make this component move in when mounted but getting
Cannot read property 'enter' of undefined
Here is a simplified code (I have all the CSS classes ready):
class Example extends React.Component {
state = {
transitionIn: false,
};
componentDidMount = () => {
this.setState({ transitionIn: true })
}
render() {
return (
<CSSTransition
in={this.state.transitionIn}
timeout={1000}
className={'wordTransition'}
>
<div>dksjfnsdkjnfj</div>
</CSSTransition>
);
}
}
https://codesandbox.io/s/rj5046zxoo

I believe that the error you were experiencing is one that you solved in the codesandbox.io link you provided above. I was having this same problem. Instead of naming the prop that takes a class name to be used as the prefix for the various transition states classNames (plural) I was using the more familiar className (singular).
To reiterate: inside the <CSSTransition> component, make sure you are using a classNames prop and not className as you would inside of a react component's html elements.
I feel that the choice on the part of the React Transition Group to use a prop called classNames in their component is confusing and should perhaps be reconsidered.

Related

Making a function component from a class component. What is props here?

I was trying to implement a drag and drop functionality to my ant design tabs component. The example they mentioned in the documentation is class based. I was trying to make it into function component but I am not sure what props are in this case.
Ant design demo
Official documentation
For example, I got confused here, this class component itself is outside another class component. How would react extract these connectDragSource, connectDropTarget, children when it has noting that is being passed from the props? And how would I extract these when I am in a function component?
class TabNode extends React.Component {
render() {
const { connectDragSource, connectDropTarget, children } = this.props;
return connectDragSource(connectDropTarget(children));
}
}
and there are some other aspects in the provided demo that are confusing to me. It would be great help if you could breakdown and explain what is happening so that I can turn this into a react functional component.
In functional component you can access props as one of your component's argument, and also instead of returning your JSX by render method, whatever you returns by your functional component, considers as your JSX output, like this:
function MyComp(props){
// do whatever you want by props (actually body of your function is equivalent to render method in class component)
return (<div>...</div>);
}
Here I implemented your tab example by function component.

How to change state of component from anywhere without Redux?

Is this bad practices or not ?
export state change function from component
import it from other file.
call the function to change state?
In this way we can change some component state from anywhere.
For example...
We want to change the Model.js state from anywhere.
Modal.js
import React from 'react';
export let toggleModal;
export default class Modal extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
};
toggleModal = this.toggleModal;
}
toggleModal = () => {
this.setState({ open: !this.state.open });
};
render() {
const { open } = this.state;
return <div style={{ color: 'red' }}>{open && 'Hello Modal'}</div>;
}
}
App.js(Some Top Level component)
import React from 'react';
import Modal from './Modal';
export default () => (
<>
...
<Modal />
...
</>
);
Somewhere.js
import React from 'react';
import {toggleModal} from './Modal';
export default () => (
<>
<h1>Hello!</h1>
<button onClick={() => toggleModal()}>open Modal!</button>
</>
);
  
But there is no reference in React Official docs, so is this bad practices ?
What React Docs recommends...
Just passing function props to change parent state from parent to children
Use context
Redux or Mobx
But, these are too complex for me.
Example code here
https://next.plnkr.co/edit/37nutSDTWp8GGv2r?preview
Everything seems pretty much overwhelming and difficult at the beginning. But as we get out hands on them, it's give us more confidence to dig into.
I would recommend to use redux that's how we tackled props drilling problem. You can dispatch a action and connect reducer to corresponding component which upon updating state will re render. This is what I recommend to most of the people to learn the tale of redux with a real life example:
Understanding Redux: The World’s Easiest Guide to Beginning Redux
Apart from this you can take Dan Abramov, author of the library, free redux course on egghead.io:
Getting Started with Redux
The problem you run into, almost immediately like your code example does is this:
It will not work: your toggleModal() method expects a this to refer to an actual component instance. When your onClick() handler fires you invoke toggleModal() as a plain function. The this context will be wrong, and so at best (in your example) you will get an error because you try to invoke something undefined, at worst (in general) you end up invoking the wrong method.
When you think about it, for any non-trivial React component you will have a hard time obtaining a reference to the actual instance that is currently being used: you have to make sure that you are not forgetting to invoke the method on the right component instance and also you have to consider that instances may be created/destroyed 'at will' for whatever reason. For example: what if your component is rendered indirectly as part of some other component's render() method? Multiple layers of indirection like that make it even harder.
Now, you could fix all that by abusing ref with abandon but you will find that now you have to keep track of which ref refers to what particular instance, if you happen to have multiple of the components to consider in one render tree...
Whenever you think one component needs to handle the state of its siblings, the solution is usually to lift the state one level up.
export default class Modal extends React.Component {
render() {
const { isOpen } = this.props;
return <div style={{ color: 'red' }}>{isOpen && 'Hello Modal'}</div>;
}
}
export default class Home {
this.state = {
isOpen: false,
};
toggleModal = () => {
this.setState({ isOpen: !this.state.isOpen });
}
render() {
const { isOpen } = this.state;
return (
<>
<h1>Hello {name}!</h1>
<button onClick={() => this.toggleModal()}>open Modal!</button>
<Modal isOpen={isOpen}/>
<p>Start editing and see your changes reflected here immediately!</p>
</>
)
}
}
This way the Home handle the state and your problem is solved.
This can get annoying if the state needs to be "drilled down" to children, that's a problem than redux or react-context can solve.
Here <Modal /> is the child component. So to call a function in a child component you can simply use Ref.
You can refer this page to get more info about Ref.
You can assign a class variable as a ref to this child and use this class variable as an object to call its function.
I found if in special case, my way is okay.
Special case means something like customAlert component.
It is okay only one instance of customAlert component mounted at a time in App.
To achieve this...
1.Use ref to access and change DOM
2.attach state changing function or component to window and call window.function
3.my case: export state changing function and import it from other file.
And here is how to do with react Context
https://next.plnkr.co/edit/EpLm1Bq3ASiWECoE?preview
I think Redux is overkill if the main thing you are interested in is to make some states-like data available and updatable throughout your App without props drilling.
For that purpose, a much simpler approach (maybe not available at the time the question was posted?) is to use react context: https://frontend.turing.edu/lessons/module-3/advanced-react-hooks.html
"context - an API given to us by React, allowing for the passing of
information to child components without the use of props
[...]
useContext - a react hook, allowing functional components to take
advantage of the context API"

GraphQL HOC messes with ref to children | React

I am using React and Apollo for my project.
I got this in my component MenuModal:
onClick = () => {
console.log(this.child)
this.child.onSubmit(); // do stuff
};
render() {
return (
<Modal.Content scrolling>
<MenuEdit
ref={ref => (this.child = ref)} // Using ref to access it's properties
selectedValues={selectedValues}
match={match}
menu={menu}
/>
My component MenuEdit has a function defined in class:
onSubmit = values => {
console.log('calling inner form submit', values);
if (this.child) {
this.child.submitFromOutside();
}
};
I should be able to call onSubmit from MenuModal right?
But I am currently getting this:
And when I console.log this.child in my onClick function I can see this:
So there's no onSubmit function there. When seeing GraphQL I wondered if it had something to do with me exporting the component with the graphQL HOC.
export default compose(
graphql(UPDATE_MENU, { name: 'updateMenu' }),
withApollo,
withRouter
)(MenuEdit);
And when I changed it just to:
export default MenuEdit;
I can see my function
So I wonder how I write my export so I still can access my function in my child. Thanks.
The HOC wrapps your component into another component. You can see this in the React devtools. You will see that the component renders a component around your wrapped component. Something like this
<Apollo(ChildComponent)>
<ChildComponent />
</Apollo>
Your ref then points to the Apollo(ChildComponen) element instance.
What you are doing here looks like an antipattern to me. In React we usually don't call functions on rendered elements (except sometimes DOM elements). The idea is rather that children call functions of their parents by receiving them as properties. The best thing in your case is to get rid of the reference and move your state and actions up the component chain. Alternatively you can use the new render prop style in react-apollo.
There was a contribution to the Apollo repository to address this issue...
https://github.com/apollographql/react-apollo/pull/410
Wrapping your component export like this withApollo(Component, { withRef: true }) will expose your child methods. Accessible using ref.current.wrappedInstance.

Is it ok to have own property in react component?

class VideoList extends Component {
constructor(props) {
super(props);
this.videoList = props.videos.map((video) => {
return <VideoListItem video={video} />
})
}
render() {
return (
<ul className="collection">
{this.videoList}
</ul>
)
}
}
I'm just wondering if it's allowed to have my own property in react component.
You can have such a property but you need to keep in mind that when you store some value in such a property react will not re render a component - so if you are using that value in render, you might not see the updated value. With setState that's not the case. If you have something in state and then update the state react will re render the component.
There was some guideline on what to put in state (from Dan Abramov), short summary here:
if you can calculate something from props, no need to put that data in state
if you aren't using something in render method, no need to put that in state
in other cases, you can store that data in state
Well, it is ok to have your own property in your react component. No one will blame you.
But don't forget to ship it with propType, it will save you lot time (catch bugs with type checking).
reference: https://facebook.github.io/react/docs/typechecking-with-proptypes.html
I think you're referring to having the videoList stored onto the Component instance?
You could store the list of videos on state, but it seems unecessary to do this and I would simplify VideoList to be a stateless functional component that renders the list of videos passed in as a prop:
const VideoList = ({ videos }) => (
<ul className="collection">
{videos.map(video => <VideoListItem video={video} />)}
</ul>
);
The official docs don't actually explain the syntax above, but it is basically syntactic sugar for a React component with no state, that just accepts props. The ({ videos }) syntax is ES6 Destructuring in action. The VideoList component receives props and this syntax extracts props.videos as a variable on the component.
Additionally, as you're rendering a list of items, you should provide some kind of unique key for each VideoListItem as you render it e.g.
<VideoListItem key={video.id} video={video} />

Ref and State difference in ReactJS

https://facebook.github.io/react/docs/more-about-refs.html
Here i got idea about ref in React JS. But still not clear why ref is being used instead of State.
Refs are normally used to access DOM elements generally to set or get the html properties such as Width, Height etc. You can also use it to get the value e.g from a text field. States define the properties of a component that can change by different actions you perform.
Just to give you an example. Suppose you want to integrate Material Design Lite (MDL) into your React app. In order to properly hook MDL into a React component, it needs to have direct access to the underlying DOM element. That might be a valid use case for using refs.
import React from 'react';
class Button extends React.Component {
componentDidMount() {
window.componentHandler.upgradeElement(this.node);
}
componentWillUnmount() {
window.componentHandler.downgradeElements(this.node);
}
render() {
return (
<button
ref={node => { this.node = node; }}
className="mdl-button mdl-js-button mdl-js-ripple-effect"
>
{this.props.children}
</button>
);
}
}
export default Button;

Resources