I'm trying to implement the card carousel using react, on clicking the next and previous buttons I'm able to scroll to the next and previous cards, and works fine. when I fast-click multiple times on the next or prev buttons it's messing up the alignment of cards.
import React, { useRef } from "react";
import Card from "./card";
import "./App.scss";
// import "./";
// import leftCircle from "./asset/leftarrow.svg";
// import rightCircle from "./asset/img_92071.png";
const CardArray = [
{ name: "first card" },
{ name: "second card" },
{ name: "third card" },
{ name: "fourth card" },
{ name: "fifth card" },
{ name: "sixth card" },
{ name: "seventh card" },
{ name: "seventh card" },
{ name: "seventh card" },
{ name: "seventh card" }
];
function App() {
let carouslRef = useRef(null);
const prev = () => {
carouslRef &&
carouslRef.current &&
carouslRef.current.scrollTo({
behavior: "smooth",
top: 0,
left: carouslRef.current.scrollLeft - 210
});
console.log(carouslRef.current.scrollLeft, carouslRef.current.clientWidth);
};
const next = () => {
carouslRef &&
carouslRef.current &&
carouslRef.current.scrollTo({
behavior: "smooth",
top: 0,
left: carouslRef.current.scrollLeft + 210
// carouslRef.current.scrollLeft + carouslRef.current.clientWidth,
});
console.log(carouslRef.current.scrollLeft, carouslRef.current.clientWidth);
};
return (
<div className="carousel">
<button className="direction" onClick={prev}>
{/* <img className="arrow" src={leftCircle} alt="left button" /> */}
<div
className="arrow"
// style={{ width: "20px", height: "20px", backgroundColor: "red" }}
></div>
</button>
<div className="card-div">
<main className="card-scroll" ref={carouslRef}>
{CardArray.map((carousel, i) => (
<Card {...carousel} key={i} />
))}
</main>
</div>
<button className="direction" onClick={next}>
{/* <img className="arrow" src={rightCircle} alt="right button" /> */}
<div
className="arrow"
// style={{ width: "20px", height: "20px", backgroundColor: "red" }}
>
next
</div>
</button>
</div>
);
}
export default App;
you can see the full code and output with this react CodeSandbox URL: https://codesandbox.io/s/gallant-voice-eh5v6p?file=/src/App.js
Related
Using ReactJS, I am trying to make a second (smaller) navbar the same way Airtable has done on their product page. My first navbar is at the top, and turns dark from transparent once I scroll. The second bar (colored purple in the screenshot to easily see) is currently behind the first navbar when I would like it to sit right underneath the header background image.
First (main) Navbar - "Header.js"
import React, { useEffect, useState } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { AppBar, IconButton, Toolbar, Collapse } from '#material-ui/core';
import SortIcon from '#material-ui/icons/Sort';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import { Link as Scroll } from 'react-scroll';
import ScrollToColor from './ColorChangeOnScroll';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
fontFamily: 'Nunito',
},
appbar: {
background: 'none',
},
appbarTitle:{
flexGrow: '1',
},
appbarWrapper:{
width: '80%',
margin: '0 auto',
},
icon: {
color: '#fff',
fontSize: '2rem',
},
colorText: {
color: '#34cbc2',
},
container: {
textAlign: 'center',
},
title: {
color: '#fff',
fontSize: '4rem',
},
goDown: {
color: '#34cbc2',
fontSize: '4rem',
},
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<section>
<div className={classes.root} id="header">
<ScrollToColor>
<AppBar className={classes.appbar} elevation={0}>
<Toolbar className={classes.appbarWrapper}>
<h1 className={classes.appbarTitle}>
Logo <span className={classes.colorText}>Colored</span>
</h1>
<IconButton>
<SortIcon className={classes.icon} />
</IconButton>
</Toolbar>
</AppBar>
</ScrollToColor>
<Collapse
in={checked}
{...(checked ? { timeout: 1000 } : {})}
collapsedHeight={50}>
<div className={classes.container}>
<h1 className={classes.title}>
Main header <br />
at <span className={classes.colorText}>title.</span>
</h1>
<Scroll to="info-card" smooth={true}>
<IconButton>
<ExpandMoreIcon className={classes.goDown} />
</IconButton>
</Scroll>
</div>
</Collapse>
</div>
</section>
);
}
Second Navbar - "StickyHeader.js"
import React, { useEffect, useState } from 'react';
import { makeStyles } from '#material-ui/core/styles';
import { AppBar, IconButton, Toolbar, Collapse } from '#material-ui/core';
import SortIcon from '#material-ui/icons/Sort';
const useStyles = makeStyles((theme) => ({
root: {
top: '1000px',
display: 'flex',
position: 'sticky',
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Nunito',
},
appbar: {
background: 'purple',
},
list: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<section>
<div className={classes.root} style={{ top: "72px" }} id="stickyheader">
<AppBar className={classes.appbar} elevation={4}>
<Toolbar className={classes.appbarWrapper}>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li>
Database
</li>
</ul>
</Toolbar>
</AppBar>
</div>
</section>
);
}
Landing Page snippet
export default function Landing() {
const classes = useStyles();
return (
<div className={classes.root}>
<CssBaseline />
<Header />
<StickyHeader />
<InfoCards />
</div>
);
}
Tried adjusting:
Separating each component into their own files to act as 'sections,' so one would sit on top of the other
Adjusting margin, marginTop in useStyles with position: relative
Same as above with position: sticky
Added style={{ top: "##px" }} to the navbar's div to see if that pushed it downwards
Images
2nd navbar behind 1st at top
2nd navbar behind 1st, scrolled
Photoshopped view of the desired outcome (where 2nd navbar is sticky and 'joins' the 1st navbar when scrolled past)
I'm not sure if I am missing something simple in the styling for these navbars, or if this needs something more complex. Any advice is appreciated in advance.
Note
The logo and header titles are a part of the first navbar. The second (purple) navbar has a very small 'Database' clickable text that is difficult to see in the first couple screenshots, right on top of 'Logo colored.'
Update
Resulting screenshot from MB_'s answer
EDIT
This is the only solution I have found...
PS:
1/ Use position: "fixed" instead of position: "sticky"
2/ There are other modifications to do... (add scroll listener,...)
Header.js
import React, { useEffect, useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { AppBar, IconButton, Toolbar, Collapse } from "#material-ui/core";
import SortIcon from "#material-ui/icons/Sort";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
import { Link as Scroll } from "react-scroll";
const useStyles = makeStyles(theme => ({
root: {
fontFamily: "Nunito"
},
appbar: {
position: "fixed",
zIndex: "9999",
background: "black"
},
appbarTitle: {
flexGrow: "1"
},
appbarWrapper: {
width: "80%",
margin: "0 auto"
},
icon: {
color: "#fff",
fontSize: "2rem"
},
colorText: {
color: "#34cbc2"
},
container: {
textAlign: "center",
height: "100vh",
marginTop: "80px",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
title: {
color: "#333",
fontSize: "4rem"
},
goDown: {
color: "#34cbc2",
fontSize: "4rem"
}
}));
export default function Header() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(true);
}, []);
return (
<div className={classes.root} id="header">
<AppBar className={classes.appbar} elevation={0}>
<Toolbar className={classes.appbarWrapper}>
<h1 className={classes.appbarTitle}>
Logo <span className={classes.colorText}>Colored</span>
</h1>
<IconButton>
<SortIcon className={classes.icon} />
</IconButton>
</Toolbar>
</AppBar>
<Collapse
in={checked}
{...(checked ? { timeout: 1000 } : {})}
collapsedHeight={50}
>
<div id="mainheader" className={classes.container}>
<h1 className={classes.title}>
Main header <br />
at <span className={classes.colorText}>title.</span>
</h1>
<Scroll to="info-card" smooth={true}>
<IconButton>
<ExpandMoreIcon className={classes.goDown} />
</IconButton>
</Scroll>
</div>
</Collapse>
</div>
);
}
StickyHeader.js
import React, { useEffect, useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { AppBar, IconButton, Toolbar, Collapse } from "#material-ui/core";
const useStyles = makeStyles(theme => ({
root: {
fontFamily: "Nunito"
},
appbar: {
background: "purple"
},
list: {
display: "flex",
justifyContent: "center",
alignItems: "center"
}
}));
export default function StickyHeader() {
const classes = useStyles();
const [checked, setChecked] = useState(false);
const [scrollY, setScrollY] = useState({ position: "relative" });
useEffect(() => {
window.addEventListener("scroll", () => {
const heightVh = document.querySelector("#mainheader").offsetHeight / 100;
if (window.scrollY > heightVh * 100) {
setScrollY({ position: "fixed", top: "80px" });
} else {
setScrollY({ position: "relative" });
}
});
return () => {
window.removeEventListener("scroll");
};
}, [scroll]);
useEffect(() => {
setChecked(true);
}, []);
return (
<>
{console.log(scrollY)}
<div className={classes.root} id="stickyheader">
<AppBar className={classes.appbar} style={scrollY} elevation={4}>
<Toolbar className={classes.appbarWrapper}>
<ul className={classes.list} style={{ listStyleType: "none" }}>
<li>
<a href="#product" data-id="product" data-is-active="true">
Database
</a>
</li>
</ul>
</Toolbar>
</AppBar>
</div>
</>
);
}
Demo : stackblitz
I have image paths in an array and I want to display the images when I map the array. My code is as follows :
import React, { Component } from 'react';
class ItemsList extends Component {
constructor() {
super();
this.state = {
products: [
{
"name": "Item 1",
"imageURL": "../images/milk.jpg"
},
{
"name": "Item 2",
"imageURL": "../images/bread.jpg"
},
]
}
}
render() {
const { products } = this.state;
return (
<div>
<div className="row">
{
products.map((val, ind) => {
return (
<div className="card mx-2 my-2 shadow-lg p-3 mb-5 bg-white rounded" key={ind} style={{ width: '345px', alignItems: 'center' }}>
<img src={val.imageURL} className="card-img-top" style={{ height: '240px', width: '240px' }} alt="product image" /> // *** Displaying Image Here ***
<div className="card-body" style={{ backgroundColor: '#a6b0bf', width: '100%', textAlign: 'center' }}>
<h5 className="card-title">{val.name}</h5>
<br />
</div>
</div>
);
})
}
</div>
</div>
);
}
}
export default ItemsList;
The image is not displaying. I want to display the image in the map method but can't get it done. Need help.
You may need to use require:
<img src={require(`${val.imageURL}`)} className="card-img-top" />
I put a submit test button but its not getting any data.
OBS about the code:
I'm using react select
I'm using filepond to upload images and files (its working fine)
ProductsModal is a modal component with rightColumn and leftColumn (left column is the form and right column there is a phone image with dynamic content inside which is a preview of the form.
My onSubmit function is a console.log with data from the form, but all I get is a empty object.
I have the following code
import React, { useState } from 'react'
import useForm from 'react-hook-form'
import Select from 'react-select'
import { FaRegFileAlt, FaRegImage } from 'react-icons/fa'
import { FilePond, registerPlugin } from 'react-filepond'
import { IoIosImages } from 'react-icons/io'
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation'
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
import TextField from '#material-ui/core/TextField'
import Button from '~/components/Button'
import ProductsModal from '~/components/Sponsor/Modals/ProductsModal'
import IconsProductImage from '~/components/Sponsor/IconsProductImage'
import Border from '~/components/Border'
import ProductBadge from '~/components/ProductBadge'
import * as S from './styled'
registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImagePreview)
export default function ModalAnnouncement({ handleCloseModal, showModal }) {
const [title, setTitle] = useState('')
const [tags, setTags] = useState([])
const [about, setAbout] = useState('')
const [files, setFiles] = useState('')
const [filePreview, setFilePreview] = useState('')
const [images, setImages] = useState('')
const [updatingFile, setUpdatingFile] = useState(false)
const [updatingImage, setUpdatingImage] = useState(false)
const { handleSubmit, setValue } = useForm()
function onSubmit(data) {
console.log('data', data)
}
function handleUpdatingFile() {
setUpdatingFile(!updatingFile)
}
function handleUpdatingImage() {
setUpdatingImage(!updatingImage)
}
function handleUpdateImages(event) {
setImages(event)
setFilePreview(event.length === 0 ? '' : URL.createObjectURL(event[0].file))
}
function handleTagsChange(tags) {
setValue('tags', tags)
setTags(tags)
}
const tagsAvailable = [
{ value: 1, label: 'artificial intelligence' },
{ value: 2, label: 'digital marketing' },
{ value: 3, label: 'big data' },
{ value: 4, label: 'blogging' },
{ value: 5, label: 'chatbot' },
{ value: 6, label: 'content marketing' },
{ value: 7, label: 'digital loyalty' },
{ value: 8, label: 'digital transformation' },
{ value: 9, label: 'email marketing' },
{ value: 10, label: 'engagement' },
]
const reactSelectStyleCustom = {
control: (base, state) => ({
...base,
boxShadow: state.isFocused ? 0 : 0,
borderColor: state.isFocused ? '#50A5D2' : base.borderColor,
borderWidth: state.isFocused ? '1px' : '1px',
'&:hover': {
borderColor: state.isFocused ? '#50A5D2' : base.borderColor,
},
}),
placeholder: defaultStyles => {
return {
...defaultStyles,
color: '#A1A1A1',
fontSize: '16px',
}
},
singleValue: provided => {
const overflow = 'visible'
const fontStyle = 'normal'
const transition = 'opacity 300ms'
return { ...provided, overflow, fontStyle, transition }
},
}
return (
<ProductsModal
modalTitle="New Announcement"
handleCloseModal={handleCloseModal}
showModal={showModal}
leftColumn={
<form onSubmit={handleSubmit(onSubmit)}>
<S.FormContainer>
<S.InputTitle>Title</S.InputTitle>
<TextField
fullWidth={true}
variant="outlined"
name="title"
placeholder="Give your announcement a title"
type="text"
value={title}
onChange={e => setTitle(e.target.value)}
/>
<div className="mt-3">
<S.InputTitle>About</S.InputTitle>
<TextField
fullWidth={true}
variant="outlined"
name="about"
multiline
rows="4"
placeholder="Tell them a little more about your announcement"
type="text"
value={about}
onChange={e => setAbout(e.target.value)}
/>
</div>
<div className="mt-3">
<S.InputTitle>Tags</S.InputTitle>
<Select
styles={reactSelectStyleCustom}
isMulti
options={tagsAvailable}
placeholder="Add tags to your announcement"
value={tags}
onChange={handleTagsChange}
/>
</div>
<div className="mt-4 mb-2">
<Border />
</div>
{updatingFile ? (
<div className="mt-2">
<div className="d-flex justify-content-center align-items-center">
<FaRegFileAlt className="mr-2" size={14} />{' '}
<S.InputTitle>Files</S.InputTitle>
</div>
<FilePond
allowMultiple={false}
files={files}
onupdatefiles={setFiles}
/>
</div>
) : (
<div className="d-flex justify-content-center">
<Button
text="Add file"
type="button"
color="#5A6978"
action={handleUpdatingFile}
width="160px"
height="40px"
/>
</div>
)}
{updatingImage ? (
<div className="mt-3">
<div className="d-flex justify-content-center align-items-center">
<FaRegImage className="mr-2" size={14} />{' '}
<S.InputTitle>Images</S.InputTitle>
</div>
<FilePond
allowMultiple={false}
files={images}
onupdatefiles={handleUpdateImages}
/>
</div>
) : (
<div className="d-flex justify-content-center">
<Button
text="Add image"
type="button"
color="#5A6978"
action={handleUpdatingImage}
width="160px"
height="40px"
/>
</div>
)}
<div className="d-flex justify-content-center">
<Button
text="Submit Form"
type="submit"
color="#5A6978"
action={(event) => { event.persist(); handleSubmit(event) }}
width="160px"
height="40px"
/>
</div>
</S.FormContainer>
</form>
}
rightColumn={
<>
<S.Phone>
<S.Screen>
<S.Content>
<div className="image-container">
{filePreview !== '' ? (
<>
<img className="animated fadeIn" src={filePreview} />
<IconsProductImage right="0" top="30%" />
<div className="ml-2 mt-3">
<S.ProductTitle>{title}</S.ProductTitle>
</div>
<div
style={{ marginTop: '-10px' }}
className="d-flex ml-2"
>
<ProductBadge
text="annoucement"
color="#D40707"
textColor="#FFF"
width="135px"
height="30px"
eventText="- engagement"
eventTextColor="#87919A"
/>
</div>
</>
) : (
<>
<img
style={{
postison: 'relative',
backgroundColor: '#CCC',
}}
className="d-flex justify-content-center align-items"
/>
<IoIosImages
style={{
position: 'absolute',
top: '125px',
right: '125px',
}}
color="red"
size={28}
/>
<div className="ml-2 mt-3">
<S.ProductTitle>
{title === '' ? (
'Title'
) : (
<S.ProductTitle>{title}</S.ProductTitle>
)}
</S.ProductTitle>
</div>
<div
style={{ marginTop: '-10px' }}
className="d-flex ml-2"
>
<ProductBadge
text="annoucement"
color="#D40707"
textColor="#FFF"
width="135px"
height="30px"
eventText="- engagement"
eventTextColor="#87919A"
/>
</div>
<S.AboutSection>
<span>{about}</span>
</S.AboutSection>
</>
)}
</div>
</S.Content>
</S.Screen>
<S.Home />
</S.Phone>
</>
}
/>
)
react-hook-form is not built to be used with controlled input elements.
Your input elements have an onChange handler attached to them which is effectively making your form a controlled one. If this is intended, you should pull the setValue method out of useForm and manually update the value to be used with react-hook-form.
See the bottom of this page to read more about using react-hook-form with controlled elements. React Hook Form FAQ
I have used a button to sort table and display message, but i want to display message according to button click.if clicked once display button clicked once else button clicked twice.
THIS IS MY CSS for displaying:
# app {
font - family: 'Open Sans', sans - serif;.table {
margin: 1e m;
display: flex;
flex - direction: column;
}.header, .row {
display: flex;
div {
flex: 1;
padding: 0.2 rem 0.4e m;
border: 1 px solid rgb(238, 238, 238);
}
}.header {
background - color: rgb(238, 238, 238);
div {
cursor: pointer;
}
}
}.search - results {
color: red;
}
here is my reactjs code:
const Row = ({ id, title, priority, type, complete }) => (
<div className="row">
{" "}
<div> {id} </div> <div> {title} </div> <div> {priority} </div>{" "}
<div> {type} </div> <div> {complete} </div>{" "}
</div>
);
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [
{
id: 403,
title: "Task 403",
priority: "High",
type: "Improvement",
complete: 100
},
{
id: 532,
title: "Task 532",
priority: "Medium",
type: "Improvement",
complete: 30
},
{
id: 240,
title: "Task 240",
priority: "High",
type: "Story",
complete: 66
}
]
};
this.compareBy.bind(this);
this.sortBy.bind(this);
}
compareBy(key) {
return function(a, b) {
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
};
}
sortBy(key) {
let arrayCopy = [...this.state.data];
arrayCopy.sort(this.compareBy(key));
this.setState({
data: arrayCopy
});
this.state.showres = [false];
}
render() {
const rows = this.state.data.map(rowData => <Row {...rowData} />);
return (
<div className="table">
{" "}
<div className="header">
{" "}
<div> ID </div> <div> Title </div> <div> Priority </div>{" "}
<div> Issue Type </div> <div> % Complete </div>{" "}
</div>{" "}
<div className="body"> {rows} </div> <br />{" "}
<div>
{" "}
<input
type="submit"
value="Sort"
onClick={() => this.sortBy("complete")}
onDoubleClick={() =>this.sortBy('id')} />{" "}
{this.state.showres ? <Results /> : null}{" "}
</div>{" "}
</div>
);
}
}
var Results = React.createClass({
render: function() {
return (
if(props.onClick)
<div id="results" className="search-results">
{" "}
<br /> button has been clicked once{" "}
else{
alert("button clicked twice");
</div>
);
}
});
ReactDOM.render(<Table />, document.getElementById("app"));
this is my html page:
<div id="app"></div>
These two buttons are sorting data but displays same message!!!!!!!!!!Anyone having knowledge of reactjs can help me.
As you are modifying your question I would Assume that you want to achieve:
Each click of the button toggles the sorting behaviour
You want to sort on every column
After all sorting options next click on button should turn off the sorting
const columns = ['id', 'title', 'priority', 'type', 'complete']
const Row = ({data}) => (
<div className="row">
{columns
.map(columnName =>
<div key={data.id + columnName}>{data[columnName]}</div>)
}
</div>
);
const data = [
{
id: 403,
title: 'Task 403',
priority: 'High',
type: 'Improvement',
complete: 100,
},
{
id: 532,
title: 'Task 532',
priority: 'Medium',
type: 'Improvement',
complete: 30,
},
{
id: 240,
title: 'Task 240',
priority: 'High',
type: 'Story',
complete: 66,
},
];
const sortKeys = [null, ...columns];
const compareBy = key => (a, b) => {
if (!key) return 0;
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
};
const Results = ({ sortKeyIndex }) => (sortKeyIndex ? <span>Sorted by {sortKeys[sortKeyIndex]}</span> : <span>Original order</span>);
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
tableData: props.data,
sortKeyIndex: 0,
};
this.sortBy.bind(this);
}
sortBy() {
const arrayCopy = [...this.props.data];
const sortKeyIndex = (this.state.sortKeyIndex + 1) % sortKeys.length;
arrayCopy.sort(compareBy(sortKeys[sortKeyIndex]));
this.setState(() => ({
tableData: arrayCopy,
sortKeyIndex,
}));
}
render() {
const { tableData, sortKeyIndex } = this.state;
return (
<div className="table">
<div className="header">
<div> ID </div>
<div> Title </div>
<div> Priority </div>
<div> Issue Type </div>
<div> % Complete </div>
</div>
<div className="body">
{tableData.map(rowData => <Row key={rowData.id} data={rowData} />)}
</div>
<br />
<div>
<input
type="submit"
value="Sort"
onClick={() => this.sortBy()}
/>
</div>
<Results sortKeyIndex={sortKeyIndex} />
</div>
);
}
}
ReactDOM.render(<Table data={data} />, document.getElementById('myApp'));
How to prevent react component click event from bubble up to document ?
I can sure that there must be something was wrong with it!
So, may be I should help myself fix it!
I just have a box component which has a click event listener, and there are some link components in that box which are effected by a document click event. How can I remove this document click event?
Can someone do me a favor?
More details info can be found in following links!
Here is the code link : https://github.com/ant-design/ant-design/issues/6576
Click has no effect, it should link to item3!
Remove document's click event
After that, it works!
What's wrong with this?
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import logo from './logo.svg';
import './App.css';
// import SideBox from './SideBox.js';
// import ContentBox from './ContentBox.js';
/*import SidebarExample from './test.js';*/
// import ReactDOMServer from 'react-dom/server';
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
import Item1 from './components/Item1.js';
import Item2 from './components/Item2.js';
import Item3 from './components/Item3.js';
import {Menu, Icon} from 'antd';
import 'antd/dist/antd.css';
const SubMenu = Menu.SubMenu;
const element = <h1>Hello, world</h1>;
const elements = () => {
return(
<h1>Hello, world</h1>
);
};
const routes = [
{
path: '/',
exact: true,
sidebar: () => <div>item1</div>,
main: () => <div><Item1 /></div>
},
{
path: '/item2',
sidebar: () => <div>item2</div>,
main: () => <div><Item2 /></div>
},
{
path: '/item3',
sidebar: () => <div>item3</div>,
main: () => <div><Item3 /></div>
}
]
class App extends Component {
constructor(props) {
super(props);
this.state = {
message: props.message,
styles: props.styles,
Any: props.any,
width: props.width,
theme: 'dark',
current: '1'
};
this.handleMenuClick = this.handleMenuClick.bind(this);
this.handleClick = this.handleClick.bind(this);
};
handleClick(e) {
console.log('click ', e);
this.setState({
current: e.key,
});
};
// ES7 property initializer syntax
handleMenuClick = (e) => {
e.preventDefault();
// e.stopPropagation();
// e.nativeEvent.stopImmediatePropagation();
console.log('this is:', this);
console.log("clicked === \n", e);
if(this.state.styles === "App-SideBox-init"){
this.setState({
message: "e.key",
styles: "App-SideBox-New",
width: "width: 40px;"
});
}
if(this.state.styles === "App-SideBox-New"){
this.setState({
message: "Hello!",
styles: "App-SideBox-init",
width: "width: 300px;"
});
}
console.log("this.state.message === ", this.state.message);
console.log("this.state.styles === ", this.state.styles);
};
componentDidMount() {
/*window.addEventListener('scroll', this.onScroll.bind(this), false);*/
// window.removeEventListener('click', this.handleMenuClick.bind(this), false);
// window.removeEventListener('click', this.handleClick.bind(this), false);
};
render() {
return (
<div className="App">
<div className="App-header">
<img id="img" src={logo} className="App-logo" alt="logo" style={this.props.width}/>
<h2>Welcome to React</h2>
</div>
<div className="App-SideBox">
<div className={this.state.styles}>
<Router>
<div>
<div style={{ display: 'flex' }}>
<div style={{
padding: '10px',
width: '30%',
background: '#f0f0f0'
}}>
<div className="SideBox-body" style={{ display: 'flex' }}>
<Menu
theme={this.state.theme}
onClick={this.handleClick}
style={{ width: 240 }}
defaultOpenKeys={['sub1']}
selectedKeys={[this.state.current]}
mode="inline"
>
<SubMenu
key="sub1"
title={
<span>
<Icon type="mail" />
<span>Navigation One</span>
</span>
}
>
<Menu.Item key="1">
<Link to="/"> item1</Link>
</Menu.Item>
<Menu.Item key="2">
<Link to="/item2">item2</Link>
</Menu.Item>
<Menu.Item key="3">
<Link to="/item3">item3</Link>
</Menu.Item>
</SubMenu>
</Menu>
</div>
</div>
</div>
</div>
</Router>
</div>
{/*onClick={this.handleMenuClick}*/}
<div onClick={this.handleMenuClick} className="App-SideBox-btn">
<span>icon</span>
</div>
</div>
<div className="App-body">
<Router>
<div>
<div>
<div style={{ flex: 1, padding: '10px' }}>
{
routes.map((route, index) => (
<Route
key={index}
path={route.path}
exact={route.exact}
component={route.main}
/>
))
}
</div>
</div>
</div>
</Router>
</div>
</div>
);
}
};
App.defaultProps = {
message: 'Hello!',
styles: 'App-SideBox-init'
};
App.propTypes = {
message: PropTypes.string.isRequired,
styles: PropTypes.string.isRequired,
width: PropTypes.string
};
export default App;
Just make all event handlers on the parent component, and then pass them to children by using props!