How do I use velocity.js UI pack effects in my react app?
With the following code thefadeOut animation is working, but slideRightIn is not.
import { VelocityTransitionGroup } from 'velocity-react';
import 'velocity-animate/velocity.ui';
class ShowForm extends React.Component {
[...]
render() {
return (
<div>
<VelocityTransitionGroup enter={{animation: "slideRightIn"}} leave={{animation: "fadeOut"}} duration="1">
{this.getActiveStep()}
</VelocityTransitionGroup>
</div>
);
}
}
The error in console is Velocity: First argument (slideRightIn) was not a property map, a known action, or a registered redirect
So the reason for this roblem was that animation name is transition.slideRightIn, not just slideRightIn.
I've been struggling with this issue for a few days...very frustrating...velocity 1.5...I've been upgrading to react 16.2. The following component code stopped working with the above mentioned error...the component is just a span wrapped in a ...Inside velocity the Velocity.Redirects[propertiesMap] only had fadeIn,fadeOut etc...not transition.xxx
import React from 'react';
import ReactDOM from 'react-dom';
import Velocity from 'velocity-animate';
import PropTypes from 'prop-types';
class StatusMessage extends React.Component {...
_animateText(text) {
var textNode = ReactDOM.findDOMNode(this.refs.textSpan),
that = this;
Velocity(textNode, "transition.shrinkIn", {
duration: 150,
delay: 50,
begin: function() {
that.setState({
text: text
});
that.animating = true;
},
complete: function() {
that.animating = false;
that.forceUpdate();
}
});
}
}
To fix it I added one import statement to my root App component...
import 'velocity-animate/velocity.ui';
class App extends React.Component { ...
I hope this helps someone else too.
Cheers!
Related
I don't understand the concept of reactivity in lit's web components architecture. From other frameworks I come up with the assumption that the following example would update without problem, but it doesn't work with lit.
I can see that the child components render method is only being called initially and not again after I click the button. But even if I call it manually via the Web Components DevTools, it doesn't re-render with the new state.
What do I have to change to make it work?
Parent component:
import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import './show-planets';
#customElement('lit-app')
export class LitApp extends LitElement {
addPlanet() {
this.planetsParent.push('Pluto')
console.log('this.planetsParent', this.planetsParent)
}
#property({type: Array}) planetsParent = ['Mars'];
render() {
return html`
<button #click="${this.addPlanet}">click</button>
<show-planets .planetsChild="${this.planetsParent}"></show-planets>
`;
}
}
Child component:
import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';
#customElement('show-planets')
export class ShowPlanets extends LitElement {
#property({type: Array}) planetsChild = ['Pluto'];
render() {
console.log('this.planetsChild', this.planetsChild);
return html`<h1>Planets are: ${this.planetsChild}</h1>`;
}
}
LitElement's property system only observes changes to the reference. Recursively listening for changes to child properties would be prohibitively expensive, especially for large nested objects.
Therefore, setting a child or grandchild property of this.planetsParent will not trigger a render.
So what can we do if we need to update a nested child? Immutable data patterns can help us.
addPlanet() {
const [...rest] = this.planetsParent;
const newItem = 'Pluto';
this.planetsParent = [newItem, ...rest];
}
Reference: https://open-wc.org/guides/knowledge/lit-element/rendering/#litelement-rendering
I am using react-codemirror and want to highlight the text 'Hello' in the Codemirror but the match-highlighter addon is not highlighting the same. Below is the code for the same.
import React, { Component } from 'react';
import { render } from 'react-dom';
import CodeMirror from 'react-codemirror';
import 'codemirror/lib/codemirror.css';
import 'codemirror/addon/search/match-highlighter';
import 'codemirror/mode/javascript/javascript';
class App extends Component {
constructor() {
super();
this.state = {
name: 'CodeMirror',
code: '//Test Codemirror'
};
}
updateCode(newCode) {
this.setState({
code: newCode,
});
}
render() {
let options = {
lineNumbers: true,
mode: 'javascript',
highlightSelectionMatches: {
minChars: 2,
showToken: /Hello/,
style:'matchhighlight'
},
styleActiveLine: true,
styleActiveSelected: true,
};
return (
<div>
<CodeMirror value={this.state.code} onChange={this.updateCode.bind(this)} options={options}/>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Current output is in the screenshot below and the word is not highlighted.
I found a solution for this issue. Inorder to enable the highlighting one need to add a css corresponding to the style property. I added the below code in css file and it started working
.cm-matchhighlight {
background: red !important
}
Now it highlights the token properly
I have a class Scroller:
class Scroller {
constructor() {
super();
}
scroll() {
alert("this works");
}
}
module.exports = Scroller;
imported into my app file...
import '../css/main.scss';
import { nodes } from './nodes';
import { Scroller } from './scrolling';
const s = new Scroller;
nodes.nav.addEventListener('click', () => {
s.scroll();
});
Why won't this console log 'this works' when I click on the nav?
PS I know for sure the event listener is set up the right way, the problem is using that method...
In addition to fixing the parentheses, a problem is
module.exports = Scroller;
You're exporting Scroller as the default export, but
import { Scroller } from './scrolling';
you're trying to import it as a named import. But no such named import exists on scrolling's exports. Import the default object from ./scrolling instead:
import Scroller from './scrolling';
I have a bunch of components with methods like these
class Header extends Component {
sidebarToggle(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-hidden');
}
sidebarMinimize(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-minimized');
}
}
I'd like to move this duplicate code to a function such as
function toggleBodyClass(className, e) {
e.preventDefault();
document.body.classList.toggle('sidebar-mobile-show');
}
Then refactor the functions above like so
sidebarMinimize(e) {
toggleBodyClass('sidebar-minimized', e);
}
In the past, I would have used a mixin, but the React docs now discourage their use.
Should I just put this function in a regular JavaScript module and import it in the component modules, or is there a particular React construct for reusing code across components?
You could make a High Order Component with those functions as so:
import React, { Component } from 'react';
export default function(ComposedComponent) {
return class ExampleHOC extends Component {
sidebarToggle(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-hidden');
}
sidebarMinimize(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-minimized');
}
render()
return <ComposedComponent { ...this.props } />;
}
}
}
Then take whatever component you wish to augment with those properties by wrapping them in the HOC:
ExampleHOC(Header);
Should I just put this function in a regular JavaScript module and import it in the component modules
Yes. That would be a pretty standard way to share code between JavaScript files. I don't believe you need to or should do anything React-related to achieve this.
However, it is important to understand that you shouldn't directly interact with the DOM ever from a React component. Thanks #ShubhamKhatri for the heads up.
In my opinion, you are correct in putting the function in a regular JavaScript module and import it in the component modules.
Since a typical answer OOP answer would be to create another class extending React.Component adding that function. Then extend that class so every component you create will have that function but React doesn't want that.
One thing to verify that you are correct is in this pattern I believe.
https://reactjs.org/docs/composition-vs-inheritance.html
inherence solve your problem , create new class that extends Component and extend from your new class to share functionality and reduce the code
class SuperComponent extends Component
{
sidebarToggle(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-hidden');
}
sidebarMinimize(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-minimized');
}
}
---------------------------------------------------------------------
class Home extends SuperComponent
{
someMethod()
{
this.sidebarMinimize();
}
}
class Main extends SuperComponent
{
someMethod()
{
this.sidebarToggle();
}
}
Other Solution
create utils class and use it in your component
class UIUtiles
{
static sidebarToggle(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-hidden');
}
static sidebarMinimize(e) {
e.preventDefault();
document.body.classList.toggle('sidebar-minimized');
}
}
class Home extends SuperComponent {
someMethod(e) {
UIUtiles.sidebarToggle(e);
UIUtiles.sidebarMinimize(e);
}
}
Going through the TodoMVC example of Redux I have found this unusual example of class inheritance. The class Header is probably extending React.Component as per usual (as should all React components, right?), but it is not explicitly stated in the code. What am I missing? How does this code work?
import React, { PropTypes } from 'react';
import TodoTextInput from './TodoTextInput';
export default class Header {
static propTypes = {
addTodo: PropTypes.func.isRequired
};
handleSave(text) {
if (text.length !== 0) {
this.props.addTodo(text);
}
}
render() {
return (
<header className='header'>
<h1>todos</h1>
<TodoTextInput newTodo={true}
onSave={::this.handleSave}
placeholder='What needs to be done?' />
</header>
);
}
}
If you don't need the methods defined by ReactComponent (setState() and forceUpdate()) you don't have to inherit from it.
As such, it isn't an example of class inheritance or magic because neither is happening here :)