I am completely new to React and I need to make an infinite scroll effect by including some divs from another component. I have found an infinite scroll library online and I am using it here in the index.js file. I have created my divs in Home.js but I am getting some errors like:-
Error: Mandatory prop "refreshFunction" missing. and TypeError: this.props.next is not a function. Can someone help me out please. I think even though I am exporting Home.js and then importing it in index.js but it is still not able to invoke the methods. Can someone please let me know what I am doing wrong and how to correct it? I have added the code below.
index.js
import React from 'react';
import { render } from "react-dom";
import InfiniteScroll from 'react-infinite-scroll-component';
import { Home } from "./components/Home";
class App extends React.Component{
render() {
return (
<InfiniteScroll
pullDownToRefresh
pullDownToRefreshContent={
<h3 style={{ textAlign: 'center' }}>↓ Pull down to refresh</h3>
}
releaseToRefreshContent={
<h3 style={{ textAlign: 'center' }}>↑ Release to refresh</h3>
}
refreshFunction={this.refresh}
next={this.generateDivs}
hasMore={true}
loader={<h4>Loading...</h4>}
endMessage={
<p style={{ textAlign: 'center' }}>
<b>Yay! You have seen it all</b>
</p>
}>
<Home/>
</InfiniteScroll>
);
}
}
render(<App />, window.document.getElementById("app"));
Home.js
import React from "react";
const style = {
display: 'flex',
alignItems: 'center',
fontSize: 40,
border: '2px solid red',
margin: ' 0 auto 10px auto',
textAlign: 'center'
}
const divs = [
<div key={1} style={{ height: 200, ...style }}>Div no 1</div>,
<div key={2} style={{ height: 200, ...style }}>Div no 2</div>,
<div key={3} style={{ height: 200, ...style }}>Div no 3</div>,
<div key={4} style={{ height: 200, ...style }}>Div no 4</div>,
<div key={5} style={{ height: 200, ...style }}>Div no 5</div>,
<div key={6} style={{ height: 200, ...style }}>Div no 6</div>,
<div key={7} style={{ height: 200, ...style }}>Div no 7</div>,
<div key={8} style={{ height: 200, ...style }}>Div no 8</div>,
];
export class Home extends React.Component{
constructor() {
super();
this.state = {
divs: divs
};
this.generateDivs = this.generateDivs.bind(this);
this.refresh = this.refresh.bind(this);
}
generateDivs() {
let moreDivs = [];
let count = this.state.divs.length;
console.log(count);
for (let i = 0; i < 30; i++) {
moreDivs.push(
<div key={'div' + count++} style={{ height: 200, ...style }}>
Div no {count}
</div>
);
}
setTimeout(() => {
this.setState({ divs: this.state.divs.concat(moreDivs) });
}, 500);
}
refresh() {
this.setState({ divs: [] });
setTimeout(() => {
this.setState({ divs });
}, 3000);
}
render() {
return (
<div>
{this.state.divs}
</div>
);
}
}
Related
I have created MyComponent( called 'InnerContainer' ) by using MUI system; styled-component. But onClick under the styled component is not working. It is working outside 'InnerContainer' but not working inside 'InnerContainer'. Don't know the reason.. please help me why it's not working.
import { useSortable } from "#dnd-kit/sortable";
import { CSS } from "#dnd-kit/utilities";
import { styled } from "#mui/system";
// import styled from '#emotion/styled'
import DeleteIcon from "#mui/icons-material/Delete";
function DraggableBox(props) {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id: props.id });
// console.log("props", props);
const outerContainer = {
transform: CSS.Transform.toString(transform),
transition,
backgroundColor: props.color,
width: "20%",
height: "25%",
display: "inline-block",
};
const InnerContainer = styled("div")({
width: "100%",
height: "100%",
display: "flex",
justifyContent: "space-between",
alignItems: "end",
fontWeight: "600",
"&:hover svg": {
color: "white",
transform: "scale(1.3)",
transition: "0.5s",
},
" .inBoxName": {
marginLeft: "0.5rem",
},
" .inBoxTrash": {
marginRight: "0.5rem",
},
});
return (
<div style={outerContainer} ref={setNodeRef} {...attributes} {...listeners}>
<InnerContainer>
<div className="inBoxName">{props.name}</div>
<div className="inBoxTrash">
<DeleteIcon onClick={() => props.removeColorBox(props.id)} />
</div>
</InnerContainer>
</div>
);
}
export default DraggableBox;
I am using React ROuter and CSS in JS for style.
I'd like to change the background color and border color for the active links child divs (navIndicator and innerIndicator)
import { css, StyleSheet } from 'aphrodite/no-important';
export default ({ task, selectedLocal, selectedScenarioId, taskId }: ITaskNavItem) => {
const isActiveNav = (match: any, location: object) => match;
const theme = getTheme();
const styles = StyleSheet.create({
navLink: {
display: 'flex',
fontSize: '12px',
textDecoration: 'none',
color: theme.palette.neutralPrimary
},
navLinkActive: {
color: theme.palette.neutralPrimary,
fontWeight: 'bold',
'.navIndicator': {
borderColor: theme.palette.themePrimary
},
'.innerIndicator': {
backgroundColor: theme.palette.themePrimary
}
},
navTitle: {
width: '100px',
textAlign: 'center',
wordBreak: 'break-word',
wordSpacing: '100px'
},
linkText: {
display: 'flex',
flexFlow: 'column',
'align-items': 'center'
},
navIndicator: {
borderRadius: '50%',
margin: '10px 0 0 0',
backgroundColor: theme.palette.white,
width: '30px',
height: '30px',
border: '2px solid',
borderColor: theme.palette.neutralPrimary,
position: 'relative'
},
innerIndicator: {
position: 'absolute',
borderRadius: '50%',
width: '20px',
height: '20px',
backgroundColor: theme.palette.neutralPrimary,
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
}
});
return (
<div className={css(styles.navLink)}>
<NavLink
exact
isActive={isActiveNav}
className={css(styles.navLink)}
activeClassName={css(styles.navLinkActive)}
to={`/selectedLocal/${selectedLocal}/scenarios/${selectedScenarioId}/tasks/${taskId}`}
>
<div className={css(styles.linkText)}>
<div className={css(styles.navTitle)}> {task.title}</div>
<div className={css(styles.navIndicator)}>
<div className={css(styles.innerIndicator)} />
</div>
</div>
</NavLink>
</div>
);
};
However, the navIndicator and innerIndicator colors doesn't change when nav link is active.
Wondering how to get the style working for active link?
NavLink element does not indicate to its children if it active. So I may suggest to get currecnt route from BrowserRouter component (your component should be child of BrowserRouter so NavLink works), compare path and set local isActive variable to indicate if specific route is active.
For example (not tested, just sample):
const StyledLinks: React.FunctionComponent<RouteComponentProps & ITaskNavItem> = ({ task, selectedLocal, selectedScenarioId, taskId, location }) => {
const to = '/selectedLocal/${selectedLocal}/scenarios/${selectedScenarioId}/tasks/${taskId}';
const isActive = to === location.pathname;
const styles = StyleSheet.create({
// ...
navIndicatorActive: {
borderColor: theme.palette.themePrimary
},
// ...
return (
<div className={css(styles.navLink)}>
<NavLink
exact
className={css(styles.navLink)}
activeClassName={css(styles.navLinkActive)}
to={to}
>
<div className={css(styles.linkText)}>
<div className={css(styles.navTitle)}> {task.title}</div>
<div className={isActive ? css([styles.navIndicator, styles.navIndicatorActive]) : css(styles.navIndicator)}>
<div className={css(styles.innerIndicator)} />
</div>
</div>
</NavLink>
</div>
);
}
// Wrap your component withRouter to get location prop
export default withRouter(StyledLinks);
I have a react component that renders fine but as soon as i add images it renders far slower and causes a few hundred miliseconds delay on the component rendering. Does anyone know a way to speed this up or what I am doing wrong?
class SearchResults extends React.Component {
render() {
//Individual container styling
const divStyle = {
float: 'left',
width: '80px',
height: '80px',
border: '5px solid pink',
borderRadius: '3px',
margin: '2px',
cursor: 'pointer',
backgroundColor: 'white'
};
const styleImage = {
maxWidth: '70px',
maxHeight: '70px',
margin: 'auto',
display: 'flex'
}
//Individual record
const startItem = (this.props.itemsPerPage * this.props.page) - this.props.itemsPerPage;//First item on page
const endItem = startItem + this.props.itemsPerPage;
//Slice is from/to
const all = searchableDatabase.slice(startItem, endItem).map((value, index) => {
return (
<div style={divStyle} >
{value.edit_title_normal}
{/*<img style={styleImage} src={'YourMemories/' + currentCollection.id + '/' + value.sequentialNumber + '/' + value.sequentialNumber + ' Thumbnail.jpg'} />*/}
</div>
)
});
//Main container
return (
<div>
<div style={{ clear: 'both', paddingTop: '20px', paddingBottom: '20px', textAlign: 'center' }}>
<Pagination allLength={searchableDatabase.length} page={this.props.page} itemsPerPage={this.props.itemsPerPage} />
</div>
<div>
{all}
</div>
</div>
);
}
}
I have a few different const functions I would like to return and render. I have it set to always render out the Main menu unless a button is pressed, which updates my state to the name of the button. Each button name has another set of buttons that it should render out (exactly like main menu), but I can't get them to render out.
My current code renders the main menu and when a button is selected instead of rendering out a new line of buttons, it renders out just the name of the button selected. I would like my conditional to render out the state name component if possible.
this.state.selected is only rendering out a String. I would like to incase it in maybe...
<this.state.selected />
However, this doesn't work.
return (
<div>
{this.state.selected === '' ? <MainMenu /> : this.state.selected }
</div>
)
EDIT - Adding all of the code for more information
import React, { Component } from 'react'
import SearchBar from 'material-ui-search-bar'
import sass from '../scss/application.scss'
import PropTypes from 'prop-types'
import RaisedButton from 'material-ui/RaisedButton'
class OverviewRender extends Component {
constructor(props) {
super(props);
this.state = {
selected: ''
}
}
handleClick(name) {
this.setState({
selected: name
});
console.log("testing" + this.state.selected);
}
render() {
const MainMenu = () => (
<div>
<RaisedButton
label="File Options"
onClick={this.handleClick.bind(this, 'FileOptions')}
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
<RaisedButton
label="Setup Options"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
<RaisedButton
label="More Options"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
<RaisedButton
label="Shift Setup"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/> <br />
<RaisedButton
label="View/Report"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
<RaisedButton
label="Troubleshooting"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
</div>
);
const FileOptions = () => (
<div>
<RaisedButton
label="Load Values"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
<RaisedButton
label="Open Values From Disk"
style={{
height: '80px',
width: '180px',
fontSize: '44px',
padding: '1px'
}}
/>
</div>
);
const { Selected } = this.state;
return (
<div>
{Selected === '' ? <MainMenu /> : <Selected />}
</div>
)
}
}
class Overview extends Component {
constructor(props){
super(props)
this.state = {
open: false
}
}
render() {
return (
<div className="menuButtons">
<br />
<OverviewRender />
</div>
)
}
}
export default Overview;
the best way if you could do this in your code
class Container extends React.Component {
constructor () {
super();
this.state = { Selected: null }
}
render () {
const { Selected } = this.state
return (
<div>
{Selected === '' ? <MainMenu /> : <Selected /> }
</div>
)
}
}
you must know that React will only render if follow its convention name. See again above
edit to reflect updated question above
import React, { Component } from 'react'
import SearchBar from 'material-ui-search-bar'
import sass from '../scss/application.scss'
import PropTypes from 'prop-types'
import RaisedButton from 'material-ui/RaisedButton'
const FileOptions = () => (
<div>
<RaisedButton label="Load Values" style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px'}} />
<RaisedButton label="Open Values From Disk" style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px'}} />
</div>
);
class OverviewRender extends Component {
constructor(props) {
super(props);
this.state = {
Selected: null
}
}
handleClick(name) {
this.setState({
Selected: name
});
console.log("testing" + this.state.Selected);
}
MainMenu = () => (
<div>
<RaisedButton label="File Options" onClick={() => this.setState({ Selected: FileOptions })} style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px' }} />
<RaisedButton label="Setup Options" style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px'}} />
<RaisedButton label="More Options" style={{height: '80px',width: '180px',fontSize: '44px',padding: '1px'}} />
<RaisedButton label="Shift Setup" style={{height: '80px',width: '180px',fontSize: '44px',padding: '1px'}} />
<br />
<RaisedButton label="View/Report" style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px' }} />
<RaisedButton label="Troubleshooting" style={{ height: '80px', width: '180px', fontSize: '44px', padding: '1px'}} />
</div>
)
render() {
const { Selected } = this.state;
return (
<div>
{this.MainMenu()}
{Selected === '' ? <MainMenu /> : <Selected />}
</div>
)
}
}
check again its initial state.
If this.state.selected is a string containing the component name, then I think this should work:
let SelectedComponent = this.state.selected;
return <div>{SelectedComponent ? <SelectedComponent /> : <MainMenu />}</div>;
The name of the variable containing the component must be capitalized. For more info see https://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components
I want my Paper Style automatically changed when the screen is big or medium or small.
here what i have imported
import React from 'react';
import reactMixin from 'react-mixin';
import ResponsiveMixin from 'react-responsive-mixin';
import Paper from 'material-ui/lib/paper';
i use ResponsiveMixin to determine screen changed
Paperstyle={this.state} where i want to have value changed automatically. and those value come from componentDidMount()
export class MainLayout extends React.Component {
constructor(props) {
super(props);
this.state = {
height: '100%',
paddingTop: 60,
marginLeft: 258,
marginRight: 6,
paddingLeft: '4%',
paddingRight: '4%'
}
}
componentDidMount() {
this.media({maxWidth: 600}, function () {
/*small*/
this.state = {
height: '100%',
paddingTop: 60,
marginLeft: '3%',
marginRight: '3%',
paddingLeft: '2%',
paddingRight: '2%'
}
}.bind(this));
this.media({minWidth: 601, maxWidth: 1024}, function () {
/*medium*/
this.state = {
height: '100%',
paddingTop: 60,
marginLeft: '3%',
marginRight: '3%',
paddingLeft: '6%',
paddingRight: '6%'
}
}.bind(this));
this.media({minWidth: 1025}, function () {
/*large*/
this.state = {
height: '100%',
paddingTop: 60,
marginLeft: 258,
marginRight: 6,
paddingLeft: '4%',
paddingRight: '4%'
}
}.bind(this));
}
render() {
const {header, content, footer} = this.props; // destructure this.props to consts
return (
<div>
<header>
{header}
</header>
<main>
<Paper style={this.state} zDepth={1}>
{content}
</Paper>
</main>
<footer>
{footer}
</footer>
</div>
)
}
}
reactMixin(MainLayout.prototype, ResponsiveMixin);
Your help will greatly appreciated :D Thanks so much!
Why do you store styles in component's state? Try this
The componentDidMount() method runs only one time after the component output has been rendered to the DOM according to the documentation. So event if screen size change, nothing will happen. #Material-UI provide a method called withStyles that helps to wrap styles and provide a classes object that containts all styles you defined. The withStyles method automatically update when screen size change. Here is and exemple:
import React from 'react';
import { withStyles } from '#material-ui/core/styles';
const styles = theme => ({
paper: { // For extra small screens (phones)
height: '100%',
paddingTop: 60,
marginLeft: '3%',
marginRight: '3%',
paddingLeft: '2%',
paddingRight: '2%',
[theme.breakpoints.up('sm')]: { // For small screens (tablets)
paddingLeft: '6%',
paddingRight: '6%'
},
[theme.breakpoints.up('md')]: { // For medium screens and above
marginLeft: 258,
marginRight: 6,
paddingLeft: '4%',
paddingRight: '4%'
}
}
})
export class MainLayout extends React.Component {
render() {
const {header, content, footer, classes} = this.props; // destructure this.props to consts
return (
<div>
<header>
{header}
</header>
<main>
<Paper className={classes.paper} zDepth={1}>
{content}
</Paper>
</main>
<footer>
{footer}
</footer>
</div>
)
}
}
// That injects `classes` object styles in your component
const YourStyledComponent = withStyles(styles)(MainLayout);
export default YourStyledComponent; // Export or do what you want with the component