I'm trying to make my slick slider slides link to an about page with react-router-dom. The problem is that it doesn't distinguish between a drag and a click. How would I make that happen, is there a way to do it with react router or would I need to add a JavaScript solution in with my own code? This is my code:
import React from "react";
import Slider from "react-slick";
import { Link } from "react-router-dom";
import "../node_modules/slick-carousel/slick/slick.css";
import "../node_modules/slick-carousel/slick/slick-theme.css";
import "./App.css";
class Movies extends React.Component {
constructor() {
super();
}
render() {
const settings = {
dots: false,
infinite: false,
speed: 500,
slidesToShow: 5,
slidesToScroll: 3,
arrows: false,
responsive: [
{
breakpoint: 1000,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
},
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
},
},
],
};
return (
<div className="App">
<h2> Single Item</h2>
<Slider {...settings}>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>1</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>2</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>3</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>4</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>5</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>6</h3>
</div>
</Link>
</div>
<div className="slickWrapper">
<Link to="/about">
<div className="customSlick">
<h3>7</h3>
</div>
</Link>
</div>
</Slider>
</div>
);
}
}
export default Movies;
This can be achieved with simple built-in mouse events. A minimal example is given below.
import React, { useState } from "react";
import Card from "#material-ui/core/Card";
import CardHeader from "#material-ui/core/CardHeader";
import CardMedia from "#material-ui/core/CardMedia";
import { useHistory } from "react-router-dom";
import Link from "#material-ui/core/Link";
export default function Card() {
const history = useHistory();
const [mouseMoved, setMouseMoved] = useState(false);
// console.log(r)
const handleClick = () => {
if (!mouseMoved) {
history.push("/");
}
};
return (
<Card className={classes.root}>
<CardHeader />
<Link
onMouseMove={() => setMouseMoved(true)}
onMouseDown={() => setMouseMoved(false)}
onMouseUp={() => handleClick()}
style={{ textDecoration: "none", cursor: "pointer" }}
>
<CardMedia image="" title="">
{" "}
</CardMedia>
</Link>
</Card>
);
}
I fixed it by removing Link and linking with JavaScript instead. It checks start cursor position and end cursor position to see if it was dragged or clicked.
let mousePosStart;
let mousePosEnd;
const mouseDownDetect = (e) => {
mousePosStart = e.pageX;
}
const mouseUpDetect = (e) => {
mousePosEnd = e.pageX;
}
const compareMouse = () => {
console.log(`start: ${mousePosStart} end: ${mousePosEnd}`);
let diffrence = mousePosStart - mousePosEnd;
if (diffrence === 0) {
window.location.href = `./about`;
}
}
I had exactly the same problem, here is the best solution:
const onLinkMouseDown = (e) => {
e.preventDefault();
}
<a
href={href}
onMouseDown={onLinkMouseDown}
key={index}
>
...slideContent
</a>
Related
I have written a simple Splide.js carousel and followed all the steps on the website such as downloading the npm package and using the correct className, yet nothing is showing up on the page.
GallerySection.js
import React from "react";
import "#splidejs/splide/css";
import Splide from "#splidejs/splide";
document.addEventListener("DOMContentLoaded", function () {
const testimonialSlider = document.getElementById("testimonial-carousel-v2");
new Splide(testimonialSlider, {
arrows: false,
autoplay: true,
speed: 700,
type: "loop",
rewind: true,
pagination: false,
perPage: 1,
}).mount();
});
function GallerySection() {
return (
<div className="splide" id="testimonial-carousel-v2">
<div className="splide__track">
<ul className="splide__list">
<li className="splide__slide">Slide 01</li>
<li className="splide__slide">Slide 02</li>
<li className="splide__slide">Slide 03</li>
</ul>
</div>
</div>
);
}
export default GallerySection;
App.js
import Navigation from "./Navigation";
import HeroSection from "./sections/HeroSection";
import GallerySection from "./sections/GallerySection";
import Footer from "./sections/Footer";
export default function App() {
return (
<div className="flex flex-col items-center justify-center object-center bg-blue-100 bg-opacity-60">
<Navigation />
<GallerySection />
<Footer />
</div>
);
}
Any suggestions if something looks off?
I would like to remove the underline from the link tag. If their is a function or method I will be very greatful for help. None of the other methods have worked and the other documentation has not helped.
import clsx from 'clsx';
import React from 'react';
import Link from '#docusaurus/Link';
import styles from './HomepageLanguages.module.css';
const LanguageList = require('../_languages_.json');
const Language = (lang) => {
const imgPath = require(`../../assets/languages/${lang.path}.png`).default;
return (
<div className={clsx('col col--3')} key={lang.path}>
<div className={styles.languageItem} style={{ backgroundColor: lang.color }}>
<div className={styles.languageImage}>
<img src={imgPath} />
</div>
<div className={styles.languageInfo}>
<div className='meta'>
<h3>
<Link to={`/docs/${lang.path}/intro`}>{lang.label}</Link>
</h3>
<p>{lang.defs}+ definitions</p>
</div>
<Link to={`/docs/${lang.path}/intro`}>See All »</Link>
</div>
</div>
</div>
);
};
export default () => {
return (
<div className={clsx(styles.homepageLanguages, 'text--left')}>
<div className={styles.flex}>
<h2 className={styles.flexLeft}>
Programming Languages
</h2>
<div className={clsx(styles.flexRight, styles.homepageLanguageLink)}>
<Link to='docs/what-is-devtionary'>See All »</Link>
</div>
</div>
<div className='row'>
{LanguageList.map(Language)}
</div>
</div>
);
};
Hi yes as mentioned by #Milosh N. the solution is to use the text-decoration: none css property. Look at an example implemented in codesanbox.
DEMO https://codesandbox.io/s/priceless-kowalevski-00ocg?file=/src/pages/index.js
import React from "react";
import Link from "#docusaurus/Link";
function HomepageHeader() {
const style = {
color: "blue",
textDecoration: "none"
};
return (
<div>
<h1>
<Link style={style} to="/">
Link
</Link>{" "}
<br />
<Link to="/">Link normal</Link>
</h1>
</div>
);
}
export default function Home() {
return <HomepageHeader />;
}
I am stumped. I have been trying to get a simple cleartext button to work. I have tried all the option available on this platform but nothing is working for me. React Hook useCallback cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook. I have no idea why this error is occurring. I am pretty new to react can anyone please help? I am trying to clear the text on a click of the clear button.
import React, { Component, useCallback, useState } from "react";
import {
Button,
Input,
Footer,
Card,
CardBody,
CardImage,
CardTitle,
CardText
} from "mdbreact";
import blankImg from "./blank.gif";
import "./style.css";
import "./flags.min.css";
import countriesList from "./countries.json";
class App extends Component {
state = {
search: ""
};
renderCountry = country => {
const { search } = this.state;
var code = country.code.toLowerCase();
const handleClick = useCallback(() => {
e.target.value = '';
}, []);
return (
<div className="col-md-3" style={{ marginTop: "20px" }}>
<Card>
<CardBody>
<p className="">
<img
src={blankImg}
className={"flag flag-" + code}
alt={country.name}
/>
</p>
<CardTitle title={country.name}>
{country.name.substring(0, 15)}
{country.name.length > 15 && "..."}
</CardTitle>
</CardBody>
</Card>
</div>
);
};
onchange = e => {
this.setState({ search: e.target.value });
};
render() {
const { search } = this.state;
const filteredCountries = countriesList.filter(country => {
return country.name.toLowerCase().indexOf(search.toLowerCase()) !== -1;
});
return (
<div className="flyout">
<main style={{ marginTop: "4rem" }}>
<div className="container">
<div className="row">
<div className="col">
<Input
label="Search Country"
icon="search"
onChange={this.onchange}
/>
<button onClick={handleClick}> Click to clear</button>
</div>
<div className="col" />
</div>
<div className="row">
{filteredCountries.map(country => {
return this.renderCountry(country);
})}
</div>
</div>
</main>
<Footer color="indigo">
<p className="footer-copyright mb-0">
© {new Date().getFullYear()} Copyright
</p>
</Footer>
</div>
);
}
}
export default App;
It is because you try to use hooks in a class based component. You can only use hooks like useCallback in functional components. Therefore you are mixing the concepts of object oriented and functional programming.
The following should do the trick:
import React, { Component, useCallback, useState } from "react";
import {
Button,
Input,
Footer,
Card,
CardBody,
CardImage,
CardTitle,
CardText
} from "mdbreact";
import blankImg from "./blank.gif";
import "./style.css";
import "./flags.min.css";
import countriesList from "./countries.json";
class App extends Component {
state = {
search: ""
};
const handleClick = (e) => {
e.target.value = '';
};
renderCountry = country => {
const { search } = this.state;
var code = country.code.toLowerCase();
return (
<div className="col-md-3" style={{ marginTop: "20px" }}>
<Card>
<CardBody>
<p className="">
<img
src={blankImg}
className={"flag flag-" + code}
alt={country.name}
/>
</p>
<CardTitle title={country.name}>
{country.name.substring(0, 15)}
{country.name.length > 15 && "..."}
</CardTitle>
</CardBody>
</Card>
</div>
);
};
onchange = e => {
this.setState({ search: e.target.value });
};
render() {
const { search } = this.state;
const filteredCountries = countriesList.filter(country => {
return country.name.toLowerCase().indexOf(search.toLowerCase()) !== -1;
});
return (
<div className="flyout">
<main style={{ marginTop: "4rem" }}>
<div className="container">
<div className="row">
<div className="col">
<Input
label="Search Country"
icon="search"
onChange={this.onchange}
/>
<button onClick={this.handleClick}> Click to clear</button>
</div>
<div className="col" />
</div>
<div className="row">
{filteredCountries.map(country => {
return this.renderCountry(country);
})}
</div>
</div>
</main>
<Footer color="indigo">
<p className="footer-copyright mb-0">
© {new Date().getFullYear()} Copyright
</p>
</Footer>
</div>
);
}
}
export default App;
useCallback hooks can only be used in functional components OR in a custom Hook NOT in class components.
You have declared your App component in class based approach i.e. Object oriented approach. To use useCallback hook for this, you should change your App component declaration to a functional component or Custom hook.
Something like this
function App() {
return (
<>Hello World!</>
);
}
you cannot useCallBack hook in class Component,we can do a simple thing to clear the button text, by using
a button text state, i.e. { btnTxt: "Clear ButtonText"} than update the state onclick
import React, { Component, useCallback, useState } from "react";
import {
Button,
Input,
Footer,
Card,
CardBody,
CardImage,
CardTitle,
CardText
} from "mdbreact";
import blankImg from "./blank.gif";
import "./style.css";
import "./flags.min.css";
import countriesList from "./countries.json";
class App extends Component {
state = {
search: "",
btnTxt: "Clear ButtonText"
};
renderCountry = country => {
const { search } = this.state;
var code = country.code.toLowerCase();
return (
<div className="col-md-3" style={{ marginTop: "20px" }}>
<Card>
<CardBody>
<p className="">
<img
src={blankImg}
className={"flag flag-" + code}
alt={country.name}
/>
</p>
<CardTitle title={country.name}>
{country.name.substring(0, 15)}
{country.name.length > 15 && "..."}
</CardTitle>
</CardBody>
</Card>
</div>
);
};
onchange = e => {
this.setState({ search: e.target.value });
};
render() {
const { search } = this.state;
const filteredCountries = countriesList.filter(country => {
return country.name.toLowerCase().indexOf(search.toLowerCase()) !== -1;
});
return (
<div className="flyout">
<main style={{ marginTop: "4rem" }}>
<div className="container">
<div className="row">
<div className="col">
<Input
label="Search Country"
icon="search"
onChange={this.onchange}
/>
<button onClick={()=> this.setState({btnText:""})}> {this.state.btnTExt}</button>
</div>
<div className="col" />
</div>
<div className="row">
{filteredCountries.map(country => {
return this.renderCountry(country);
})}
</div>
</div>
</main>
<Footer color="indigo">
<p className="footer-copyright mb-0">
© {new Date().getFullYear()} Copyright
</p>
</Footer>
</div>
);
}
}
export default App;
I need to click on the custom arrows, what would the slider work. I know that there is a trigger in JQuery or something, but what can i do in react ?
You can see api slick-slider on this link https://react-slick.neostack.com/docs/example/custom-arrows
..................................................................................................................................................................
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
// CLICK HERE
<div><span>arrows<span><span>arrows<span></div>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
I found this solution
document.getElementsByClassName('slick-next')[0].click()
but I do not know if it is good to use in react
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!