React-Virtualized InfiniteLoader lags on passing props to rendered rows - react-virtualized

I just got started with react-virtualized and setup an InfiniteLoader->AutoSizer->VirtualScroller. Unfortunately, the rows that are lazily loaded aren't getting their props immediately. They render as if the props were null or undefined. If I scroll on past them and then scroll back to them, they are rendered correctly. Also, other than the initial pre-fetched rows, if I scroll slowly, all new rows render okay. If I send the scroll wheel flying, however, it will "land" on a set of "sub-rendered" rows. Given the code below, what am I doing wrong?
import React, { PropTypes } from 'react'
import { stitch } from 'keo'
import CSSModules from 'react-css-modules'
import css from './component.scss'
import R from 'ramda'
import { Divider, Paper } from 'material-ui'
import { AutoSizer, InfiniteLoader, VirtualScroll } from 'react-virtualized'
import 'react-virtualized/styles.css'
import Row from 'components/Row'
let list = R.repeat({score: 100, volume: 999}, 10)
function isRowLoaded ({ index }) {
return !!list[index]
}
function loadMoreRows ({ startIndex, stopIndex }) {
// fake loading
list = R.insertAll(startIndex, R.repeat({score: 100, volume: 999}, stopIndex - startIndex), list)
return Promise.resolve()
}
const render = ({ props }) => (
<div>
<Paper zDepth={2}>
<Paper zDepth={2}>
</Paper>
<div>
<InfiniteLoader
isRowLoaded={isRowLoaded}
loadMoreRows={loadMoreRows}
rowCount={1000}
>
{({ onRowsRendered, registerChild }) => (
<AutoSizer>
{({ height, width }) => (
<VirtualScroll
ref={registerChild}
width={width}
height={height}
rowCount={1000}
rowHeight={72}
onRowsRendered={onRowsRendered}
rowRenderer={
({ index }) =>
<div>
<Row {...list[index]} />
<Divider />
</div>
}
/>
)}
</AutoSizer>
)}
</InfiniteLoader>
</div>
</Paper>
</div>
)
export const View = CSSModules(stitch({ render }), css)

Related

"Expected `onClick` listener to be a function, instead got a value of `string` type (ReactJS/MaterialUI)

I create a login button that onClick logs the user in and then the generated information is stored in the local storage, but I keep getting an "Expected onClick listener to be a function, instead got a value of string type. I am using reactJS to do so.
// Global Navigation Bar
import { connect } from "react-redux";
import React, { Component } from "react";
import cognitoUtils from "lib/cognitoUtils";
import "assets/css/Base.css";
import Avatar from "#material-ui/core/Avatar";
import Tooltip from "#material-ui/core/Tooltip";
import AccountCircleOutlinedIcon from "#material-ui/icons/AccountCircleOutlined";
import AccountCircleIcon from "#material-ui/icons/AccountCircle";
const mapStateToProps = state => {
return { session: state.session };
};
class SignInOut extends Component {
onSignOut = e => {
e.preventDefault();
cognitoUtils.signOutCognitoSession();
};
state = {
on: true
};
toggle = () => {
this.setState({
on: !this.state.on
});
};
render() {
return (
<div>
<button className="profile_button" onClick={this.toggle}>
{this.state.on && (
<div>
{this.props.session.isLoggedIn ? (
<div>
<a
className="Home-link"
href="/home"
onClick={this.onSignOut}
>
<Tooltip title="Profile">
<Avatar className="profile_icon">
<AccountCircleIcon className="profile_icon_in" />
</Avatar>
</Tooltip>
</a>
</div>
) : (
<div>
<a
className="Home-link"
href={cognitoUtils.getCognitoSignInUri()}
onClick="/home"
>
<Tooltip title="Profile">
<Avatar className="profile_icon">
<AccountCircleOutlinedIcon className="profile_icon" />
</Avatar>
</Tooltip>
</a>
</div>
)}
</div>
)}
</button>
</div>
);
}
}
export default connect(mapStateToProps)(SignInOut);
Because you are passing String type to onClick
onClick="/home"
You need to pass a function as stated in the error. something like you did before
onClick={this.onSignOut}

How to display an svg image in reactjs

I am working on a web application with Nodejs and Reactjs and currently i'm retrieving data from the mongo database and displaying it with react.
Here is some code :
import React, {Component} from 'react';
import axios from '../../node_modules/axios';
import {Col,Card} from 'react-bootstrap';
import {BrowserRouter as Router,Link, useRouteMatch} from 'react-router-dom';
const Brand = props => (
<Col lg="4" className="d-inline-block">
<Link to="/admin/Marques/MarqueDetails/1">
<Card className="marque-card" style={{ width: '100%' }}>
<p>{props.brand.name}</p>
<Card.Img className="marque-card" variant="top" src={`../../public/` +
props.brand.imgUrl} />
</Card>
</Link>
</Col>
)
class cardBrand extends Component {
constructor(props) {
super(props);
this.state = {brands: []};
}
componentDidMount() {
axios.get('http://localhost:5000/brand/')
.then(response => {
this.setState({ brands: response.data })
})
.catch((error) => {
console.log(error);
})
}
brandList() {
return this.state.brands.map(currentBrand => {
return <Brand brand={currentBrand} key={currentBrand._id}/>;
})
}
render() {
return(
<Col lg="12">
{ this.brandList() }
</Col>
)
}
}
export default cardBrand;
As you can see i have the img/brand folders inside the public folder and the props.brand.imgUrl contains the path and the image name, but unfortunately it's not working on the browser, here is an image :
P.S : i already tried react-svg but nothing happened, maybe because i didn't know how to use it.
Thank you in advance.
From the screenshot, looks like your svg path is img/brand/svg-name.svg. to display the image don't include public in your source. for example, to display images in public/img/brand you use
// without specifying public directory
<img alt="test" src={'/img/brand/svg-name.svg'}/>
Change your card src to
<Card.Img className="marque-card" variant="top" src={`/${props.brand.imgUrl}`} />

How to display images in Bootstrap carousel using React

So I have a component(Posts) in which a loop through all the posts from the Database. In the component, I 'embedded' another component(PostItem) so I dont have to create a different component for viewing individual entries. Now inside the PostItem component I have another component with the name of 'PostGallery'.
This is the current code that I have in PostItem.js file:
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PostGallery from '../posts/PostGallery';
const PostItem = ({
post: { _id, text, name, files, avatar, user, likes, comments, date },
}) => (
<article className={_id}>
<Link to={`/posts/${_id}`}>
<div id="carouselExampleIndicators" className="carousel slide" data-ride="carousel">
<div className="carousel-inner">
{files.slice(0, 5).map((file, index) => (
<PostGallery key={index} post={file} />
))}
</div>
</div>
</Link>
</article>
);
PostItem.propTypes = {
post: PropTypes.object.isRequired,
};
export default connect(
null, null
)(PostItem);
When posting an entry the user can post URL from images separated by comma which is working just fine. The problem comes when displaying it in the front-end.
This is what I have in my PostGallery component:
import React from 'react';
import PropTypes from 'prop-types';
const PostGallery = ({
post: { files }
}) => {
return (
<div className="">
{post.files.length > 0 ? (
post.files.map(file => (
<img key={file} src={file} alt="" />
))) : (
<p>No images found</p>
)
}
</div>
);
};
PostGallery.propTypes = {
post: PropTypes.object.isRequired,
};
export default PostGallery;
I believe this should be easy but somehow its just now working and the console it's not trowing me any errors related to it. So if you guys can help...
Thanks!

Scroll to particular component in Preact

i am working on preact app and i have different components imported in a single page, i want to click on button in header and scroll to particular component.
this is my parent component
<div class={style.root}>
<Header />
<Landing />
<HowItWorks />
<BrowserCatalogue />
<ContactUs />
<Footer />
</div>
and in my header i have 3 buttons
<div class={styles.headerItems}>
<span style={styles.pointer}>Working</span>
<span style={styles.pointer}>Catalogue</span>
<span style={styles.pointer}>Contact</span>
</div>
</div>
like when i click on working my page should scroll to HowItWorks component.any help?
Let me help you friend. You should introduce refs in your parent component.
We will wrap each section in a div and give it a ref prop.
Here is sandbox for your reference: https://codesandbox.io/s/navbar-click-scroll-into-section-us8y7
Parent Component
import React from "react";
import ReactDOM from "react-dom";
import Header from "./Header";
import HowItWorks from "./HowItWorks";
import BrowserCatalogue from "./BrowserCatalogue";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: null
};
}
//refs
howItWorks = React.createRef();
browserCatalogue = React.createRef();
changeSelection = index => {
this.setState({
selected: index
});
};
componentDidUpdate() {
this.scrollToSection(this.state.selected);
}
scrollToSection = index => {
let refs = [this.howItWorks, this.browserCatalogue];
if (refs[index].current) {
refs[index].current.scrollIntoView({
behavior: "smooth",
block: "nearest"
});
}
};
render() {
return (
<div className="App">
<div>
<Header changeSelection={this.changeSelection} />
</div>
<div ref={this.howItWorks}>
<HowItWorks />
</div>
<div ref={this.browserCatalogue}>
<BrowserCatalogue />
</div>
</div>
);
}
}
Header
const Header = (props) => {
const { changeSelection } = props;
return (
<div style={{ background: "green" }}>
<span onClick={() => changeSelection(0)}>Working</span>{" "}
<span onClick={() => changeSelection(1)}>Catalogue</span>{" "}
<span>Contact</span>
</div>
);
}
Workflow:
Each component gets a ref, and we keep that in memory for when we
need to scroll.
Header, we defined a handler in parent called changeSelection()
and we pass it as prop. It takes an index and we use that index to
update the parent state.
Each link, "Working", "Catalogue", etc, will correspond to an index
that matches with a ref in our parent, so setting up an onClick() handler for each span will allow us to pass in that index to changeSelection()
parent state is updated, triggers componentDidUpdate(), in there
we run scrollToSection() which you guessed it takes in an index (stored in our state as "selected"). Create an array of our refs, and simply use the matching index to locate that ref and scroll to that component.

Does react-virtualized work inside a functional component?

I am asking because the examples I've seen are all in es6 classes.
And: I refactored my es6 class to a functional component. Now no rows appear any more. And no error either. Seems like the row renderer simply renders no rows any more.
Yes, you can use function component with react-virtualized
Does it perform as well as class component? I have no idea, tell me in comment ;)
Example:
import React from 'react'
import {Grid, Typography} from '#material-ui/core'
import PackageItem from './PackageItem'
import {PackagesByCategory} from '../functions/src/types'
import {makeStyles} from '#material-ui/core/styles'
import {WindowScroller, AutoSizer, List, ListRowRenderer, CellMeasurer, CellMeasurerCache} from 'react-virtualized'
const useStyles = makeStyles(theme => ({
container: {
minHeight: "80vh",
width: "100%"
},
title: {
marginTop: 64,
},
}))
const cache = new CellMeasurerCache({
defaultHeight: 60,
fixedWidth: true
});
const PackageCategoriesList = ({packagesByCategories}: PackageCategoriesList) => {
const classes = useStyles()
if(!packagesByCategories) {
return <></>
}
const rowRender: ListRowRenderer = ({index, key, style, parent}) => {
const packageByCategory = packagesByCategories[index]
return <CellMeasurer
cache={cache}
columnIndex={0}
key={key}
overscanRowCount={10}
parent={parent}
rowIndex={index}
>
<Grid item key={key} style={style}>
<Typography variant="h1" className={classes.title}>
{packageByCategory.category.name}
</Typography>
</Grid>
</CellMeasurer>
}
return <div className={classes.container}>
<WindowScroller
scrollElement={window}>
{({height, isScrolling, registerChild, onChildScroll, scrollTop}) => (
<div className={classes.list}>
{console.log("re der list" , height, isScrolling, scrollTop)}
<AutoSizer disableHeight>
{({width}) => (
<div ref={registerChild}>
<List
autoHeight
height={height}
isScrolling={isScrolling}
onScroll={onChildScroll}
overscanRowCount={2}
rowCount={packagesByCategories.length}
rowHeight={cache.rowHeight}
rowRenderer={rowRender}
scrollTop={scrollTop}
width={width}
/>
</div>
)}
</AutoSizer>
</div>
)}
</WindowScroller>
</div>
}
export default PackageCategoriesList

Resources