React + Spring - feels laggy - reactjs

My page which downloads and displays data from API does Spring animations and they are really laggy. It is quite ok when there are like 1-5 items (but still choppy) and when there are like 20-30 items it's just horrible.
This is my component which animates:
const FadeInSpring = ({ children, del }) => {
return (
<Spring from={{ opacity: 0, marginTop: 100 }} to={{ opacity: 1, marginTop: 0 }} config={{ delay: del }}>
{(props) => <animated.div style={props}>{children}</animated.div>}
</Spring>
);
};
And this is card I animate:
<section className="row justify-content-center p-1">
<article className="col-12 col-md-5">
<div className="card shadow">
<div className="card-body">
<h2 className="card-title">Ingredients:</h2>
<p>{item.strIngredient1}</p>
</div>
</div>
</article>
</section>;
Everything together just looks like this:
<FadeInSpring>
<HeaderCard/>
</FadeInSpring>
Am I doing something wrong?
EDIT: Adding the link so you can see it yourself. Maybe you will notice the problem. https://ablaszkiewicz.github.io/react-portfolio/#/recipes

Related

ScrollMagic React

How I can do something like planet on this link with help ScrollMagic in React?
My code
<div className={styles.containerMain}>
<div>
<Controller>
<Scene duration={300} triggerElement="#first-container" offset={500}>
{(progress) => (
<Tween
from={{
css: {
top: '0',
},
ease: 'Circ.easeOutExpo',
}}
to={{
css: {
top: '-500px',
},
ease: 'Circ.easeOutExpo',
}}
totalProgress={progress}
paused
>
<div id="first-container" style={{ height: '100vh', position: 'relative' }}>
<div className={styles.container}>
<div className={styles.contentContainer}>
<div className={styles.textSmall}>We</div>
<div className={styles.textLarge}>Deliver</div>
<div className={styles.containerText}>
<div className={styles.textSmall}>Quality</div>
<div className={styles.textSmall}>Software </div>
</div>
<div className={styles.textLarge}>Globally</div>
<div className={styles.globe}>
<Globe /> //this is image svg
</div>
</div>
</div>
</div>
</Tween>
)}
</Scene>
</Controller>
</div>
</div>
I need:
I see part of my image and than I am scrolling and I see full of my image (image replace text), than do something like in link

How to make react-spring <Spring> replay animation?

I have a simple react site which displays drinks from the drinks-api. It basically works like this: when user presses button, the query gets updated, fetchItems runs and items are displayed this way
<Spring from={{ opacity: 0, marginTop: 100 }} to={{ opacity: 1, marginTop: 0 }} config={{ delay: 400 }}>
{(props) => (
<div style={props}>
{drinks
? drinks.map((drink) => (
<DrinkCard
title={drink.strDrink}
image={drink.strDrinkThumb}
alcohol={drink.strAlcoholic}
category={drink.strCategory}
/>
))
: () => (
<div className="col-6 col-md-4 p-0">
<h1>NO RESULTS</h1>
</div>
)}
</div>
)}
</Spring>
For now this animation works only once when page loads. How do I force it to run on every search?
You should add reset to your Spring component like this:
<Spring
from={{ opacity: 0, marginTop: 100 }}
to={{ opacity: 1, marginTop: 0 }}
config={{ delay: 400 }}
reset
>
Here is an example: https://codesandbox.io/s/dank-moon-sq7v9?file=/src/App.js:348-503

What is best way to do lazy loading in a Next js Application?

I checked the documentation about Lazy Loading components on the official next js docs page (https://nextjs.org/learn/excel/lazy-loading-components).
I tried the steps mentioned and it did not work for me. Below is the piece of code that I want to lazy-load:
<div id="cards" className={index.sectionCards} style={{paddingBottom: '0px'}}>
<div className="title" style={{marginBottom: "0px", paddingBottom: "0px"}}>
Take a Look at Our Exciting Range of Cards
</div>
{this.renderCards()}
<div></div>
</div>
Here the renderCards function makes a call to a backend API and gets images from AWS S3, this whole process takes a lot of time and hence increases the overall page load time, below is the code for the function renderCards:
renderCards() {
const keys = Object.keys(this.state.products);
const valid_keys = ['Specials', 'New Beginnings', 'Expressions', 'Celebrations' ];
if(keys.length == 0) return <div></div>
return (<div className={index.cards}>
{
keys.map((key) => {
if(valid_keys.indexOf(key) > -1) return <div style={{ width: '80%', margin: '0 auto' }}>
<div className={index.category}>{key}</div>
<div style={{ display: 'flex', overflow: 'scroll' }} >
{this.state.products[key].map((c) => {
if(c.status == 'PRODUCT_ACTIVE') {
return <img onClick={() => this.onClickProduct(c)} className={index.cardImage} src={`<backend URL here>`} />
}
})}
</div>
</div>
})
}
</div>)
}
The objective was to lazy load this component to improve the overall page speed.
If anyone knows a way to solve this problem, please share.
Documentation for dynamic/lazy loading with nextjs
const Cards = () => {
const renderCards = () => {
const keys = Object.keys(this.state.products);
const valid_keys = [
"Specials",
"New Beginnings",
"Expressions",
"Celebrations",
];
if (keys.length == 0) return <div></div>;
return (
<div className={index.cards}>
{keys.map((key) => (
<Fragment key={key}>
{valid_keys.indexOf(key) > -1 && (
<div style={{ width: "80%", margin: "0 auto" }}>
<div className={index.category}>{key}</div>
<div style={{ display: "flex", overflow: "scroll" }}>
{this.state.products[key].map((c) => (
<Fragment key={c.id}>
{c.status === "PRODUCT_ACTIVE" && (
<img
onClick={() => this.onClickProduct(c)}
className={index.cardImage}
src={`<backend URL here>`}
/>
)}
</Fragment>
))}
</div>
</div>
)}
</Fragment>
))}
</div>
);
};
return (
<div
id="cards"
className={index.sectionCards}
style={{ paddingBottom: "0px" }}
>
<div
className="title"
style={{
marginBottom: "0px",
paddingBottom: "0px",
}}
>
Take a Look at Our Exciting Range of Cards
<div>{this.renderCards()}</div>
</div>
</div>
);
};
```
above code is not my code but a replication of the code in the question.
```
```
from nextjs
For the best understanding of dynamic/lazy load see link provided.
import dynamic from "next/dynamic";
```
import LoadSpinner from "../loadSpinner";
const Cards = dynamic(() => import("./cards"), {
```
this can be a custom loader or a node_module installed or just <div>Loading...</div> the loading: function will display while waiting for the import fucntion to load.
loading: () => <LoadSpinner />,
```
});
const CardContainer = () => ( <Cards /> );

I am trying to hide and show an element based on states but it could not worked?

the problem is that I am trying to hide and show elements based on states with conditional rendring but it would not worked .
I have set the state of element and pass the method in onmouseover and onmouse leave event first time it worked for one element when I repeat the same process for second element it would not worked.
constructor(props)
{
super(props)
this.state = {
show: false,
opticare: false
}
this.handleSwitch = this.handleSwitch.bind(this)
this.leave = this.leave.bind(this)
this.handleOpti = this.handleOpti.bind(this)
this.handleCare = this.handleCare.bind(this)
}
handleSwitch = () => {
this.setState({
show: !this.state.switch
})
}
leave = () => {
this.setState({
show: this.state.switch
})
}
handleOpti = () => {
this.setState({
opticare: !this.state.opticare
})
}
handleCare = () => {
this.setState({
opticare: this.state.opticare
})
}
render()
{
let className = 'reading-friends'
if (this.state.show) {
className = 'reading-friends visible'
} else if (!this.state.show) {
className = 'reading-friends invisible'
}
let addClass = 'opti-care'
if (this.state.opticare) {
addClass = 'opti-care visible'
} else if (!this.state.opticare) {
addClass = 'opti-care invisible'
}
return (
<div>
<div>
<div className="row ">
<div className="row ">
<div className={className} style={{ textAlign: 'center' }}>
<h1 className="heading" style={{
fontSize: '50px',
fontWeight: 'bold',
marginTop: '140px',
marginBottom: '200px',
fontFamily: 'catamaran,sans-serif'
}}>Reading Friends</h1>
<p className="parah">Reading Friends is designed to engage young children by
promoting interactive learning through games, puzzles,<br/>
and music. Appealing to children's instinctual inquisitiveness,
Reading Friends brings education to life with exciting graphics,<br/>
spirited sound and creative activities
that help them learn to read, while entertaining them through play.</p>
</div>
</div>
</div>
<div className="row d-flex justify-content-center">
<div style={{ textAlign: 'center' }} className={addClass}>
<h1 style={{
fontSize: '50px',
fontWeight: 'bold',
marginBottom: '200px',
fontFamily: 'catamaran,sans-serif'
}}>Opticare Solution</h1>
<p>OptiCare Solution is a complete mini ERP for opticians and optometrists.<br/>
We are the first to bring such an extensive solution in the field of Optometry,<br></br>
providing features that are robust and easy to use.</p>
</div>
</div>
<div className="row"></div>
</div>
<div style={{ marginTop: '270px' }} className="row ">
<div className="col-lg-3 col-sm-3 col-3 d-flex justify-content-center">
<a href="https://play.google.com/store/apps/details?id=com.planetreading.readingfriends">
<img onMouseOut={this.leave} onMouseOver={this.handleSwitch}
src="http://newstate.io/wp-content/uploads/2019/07/work-reading-friends-colored.png"
alt="" class="we-do-img we-work-img img-responsive grayscale"/>
</a>
</div>
<div className="col-lg-3 col-sm-3 col-3 d-flex justify-content-center">
<img onMouseOut={this.handleCare} onMouseOver={this.handleOpti}
src="http://newstate.io/wp-content/uploads/2019/07/work-opticare-colored.png"
alt="" class="we-do-img we-work-img img-responsive grayscale"/>
</div>
</div>
</div>
)
}
There's no need to create two separate functions for both onMouseEnter and onMouseLeave. You can use a single function for both event-listeners.
Just create two functions, one for each state-value you want to toggle. In the code below, we'll use handleSwitch and handleOpti.
See working sandbox: https://codesandbox.io/s/naughty-cookies-4mcwt
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
show: false,
opticare: false
};
}
handleSwitch = () => {
this.setState({
show: !this.state.show
});
};
handleOpti = () => {
this.setState({
opticare: !this.state.opticare
});
};
render() {
let className = "reading-friends";
if (this.state.show) {
className = "reading-friends visible";
} else if (!this.state.show) {
className = "reading-friends invisible";
}
let addClass = "opti-care";
if (this.state.opticare) {
addClass = "opti-care visible";
} else if (!this.state.opticare) {
addClass = "opti-care invisible";
}
return (
<div>
<div>
<div className="row ">
<div className="row ">
<div className={className} style={{ textAlign: "center" }}>
<h1
className="heading"
style={{
fontSize: "50px",
fontWeight: "bold",
marginTop: "140px",
marginBottom: "200px",
fontFamily: "catamaran,sans-serif"
}}
>
Reading Friends
</h1>
<p className="parah">
Reading Friends is designed to engage young children by
promoting interactive learning through games, puzzles,
<br />
and music. Appealing to children's instinctual
inquisitiveness, Reading Friends brings education to life with
exciting graphics,
<br />
spirited sound and creative activities that help them learn to
read, while entertaining them through play.
</p>
</div>
</div>
</div>
<div className="row d-flex justify-content-center">
<div style={{ textAlign: "center" }} className={addClass}>
<h1
style={{
fontSize: "50px",
fontWeight: "bold",
marginBottom: "200px",
fontFamily: "catamaran,sans-serif"
}}
>
Opticare Solution
</h1>
<p>
OptiCare Solution is a complete mini ERP for opticians and
optometrists.
<br />
We are the first to bring such an extensive solution in the
field of Optometry,
<br />
providing features that are robust and easy to use.
</p>
</div>
</div>
<div className="row" />
</div>
<div style={{ marginTop: "270px" }} className="row ">
<div className="col-lg-3 col-sm-3 col-3 d-flex justify-content-center">
<a href="https://play.google.com/store/apps/details?id=com.planetreading.readingfriends">
<img
onMouseOut={this.handleSwitch}
onMouseOver={this.handleSwitch}
src="http://newstate.io/wp-content/uploads/2019/07/work-reading-friends-colored.png"
alt=""
class="we-do-img we-work-img img-responsive grayscale"
/>
</a>
</div>
<div className="col-lg-3 col-sm-3 col-3 d-flex justify-content-center">
<img
onMouseOut={this.handleOpti}
onMouseOver={this.handleOpti}
src="http://newstate.io/wp-content/uploads/2019/07/work-opticare-colored.png"
alt=""
class="we-do-img we-work-img img-responsive grayscale"
/>
</div>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
In your leave and handleSwitch function, you are using switch property of the state instead of show property.
Also, there is no need to use bind if you are using arrow functions.

Reactjs - Basic column splitting using flexbox

I'm currently trying to learn the basics of React so I thought I'd try to mock-up another website. Currently, I'm trying to build a header that looks like Airbnb's
Unfortunately, I can't seem to figure out the aligning and how to get the logo to be all the way on the left side.
Any advice would be appreciated! Thanks!
<Flexbox flexDirection="column">
<Flexbox element="header" height="60px">
<div style={{ flexGrow: 0}}>
<img src={Logo} />
</div>
<div style={{flexGrow: 8}}>
<SearchBar
onChange={() => console.log('onChange')}
onRequestSearch={() => console.log('onRequestSearch')}
style={{
margin: '0 auto',
maxWidth: 800
}}
/>
</div>
<div>
<Button>Become a host</Button>
</div>
<div>
<Button>Sign up</Button>
</div>
<div>
<Button>Log in</Button>
</div>
</Flexbox>
</Flexbox>

Resources