Why my screen is flashing when i call the pros function - Reactjs - reactjs

am making a slider, when i click on an item to slide to the second item, the screen flashs when the function is called ( the func that changes the items )
This comes exactly when clickAction(); is called.
Here is the demo : https://gfycat.com/ultimatetiredequestrian
PS: the click is handled in another file, here is some code :
const VerticalCarousel = ({ clickActionTransfer }) => {
.
..
...
<button
data-glitch={item.type}
type="button"
onClick={clickActionTransfer}
key={i}>
CLICK
{item.type}
</button>
};
This is my <SLider/> :
import React, { useState, useEffect } from "react";
import VerticalCarousel from "./carousel/VerticalCarousel";
const Slider = ({ getData, idd, clickAction, children }) => {
const [dataSlider, setDataSlider] = useState([]);
const [displayTitleState, setDisplayTitleState] = useState(true);
const [displayCarouselState, setDisplayCarouselState] = useState(true);
const [currentIndex, setCurrentIndex] = useState(0);
const [length, setLength] = useState(children.length);
const handleSlideClick = () => {
if (currentIndex < length - 1) {
setCurrentIndex((prevState) => prevState + 1);
}
setDisplayCarouselState(false);
setTimeout(() => {
setDisplayTitleState(false);
clickAction();
}, 1000);
setTimeout(() => {
setDisplayTitleState(true);
setDisplayCarouselState(true);
}, 2600);
};
useEffect(() => {
setLength(children.length);
setDataSlider(getData);
}, [getData, children]);
return (
<div className="slider__container">
{dataSlider.map((i) => {
return (
idd === i.id && (
<div key={i.id}>
<div
style={{
transform: `translateX(-${currentIndex * 100}%)`,
display: "flex",
transition: "all .5s linear",
}}
>
{" "}
{children}{" "}
</div>
<div className="slider__content">
<div
className={
"slider__left " + (i.theme === "light" ? "light-theme" : "")
}
>
<div className="slider__progressBar">
{" "}
{i.progressBar.nb1}{" "}
<span className="slider__progressBar-lightTxt">
{" "}
{i.progressBar.nb1}
</span>{" "}
{i.progressBar.text}
</div>
<h1 className={displayTitleState ? "showTitle" : "hideTitle"}>
{" "}
{i.title}{" "}
</h1>
</div>
<div
className={`slider__right ${
displayCarouselState ? "showCarousel" : "hideCarousel"
} ${i.theme === "light" ? "light-theme" : ""}`}
>
<VerticalCarousel
data={i.slider}
clickActionTransfer={handleSlideClick}
/>
</div>
</div>
</div>
)
);
})}
</div>
);
};
export default Slider;
App.js :
import React, { useState, useEffect } from "react";
import Slider from "./Slider";
import "./App.scss";
function App() {
const [loadSlide, setLoadSlide] = useState(0);
const [data, setData] = useState([]);
const handleclick = () => {
setLoadSlide(loadSlide + 1);
};
useEffect(() => {
setLoadSlide((loadSlide) => loadSlide + 1);
fetch("/data.json")
.then((response) => response.json())
.then((json) => {
setData(json.lvmh.sliders);
});
}, []);
return (
<div className="App">
<div
className={
"slider " +
(loadSlide >= 1 &&
loadSlide <= data.length &&
loadSlide + 1 &&
`ifSlider`)
}
>
<>
{loadSlide >= 0 && loadSlide <= data.length && loadSlide + 1 && (
<Slider clickAction={handleclick} idd={loadSlide} getData={data}>
{data.map((img) => {
return (
<img className={"slider__bg---- "} src={img.img} alt="" />
);
})}
</Slider>
)}
</>
</div>
</div>
);
}
export default App;

I found it, i don't know why but the bug comes from the browser console when it's opened ! weird !

Related

How can i stop my array from shuffling onClick

So i'm building a Quiz App using Next Js and everything was going fine until i find out my array keeps Re-shuffling onClick of any button and i'm stumped on how to stop it.....I have tried adding e.preventDefault on all the button functions but nothing is working, So anytime i click an option it reshuffles the array thereby causing newArray[0] to always get the wrong answers, Any ideas on how i can stop reshuffling onClick??, Thanks in Advance
import axios from "axios";
import Axios from "axios";
import React, { useContext, useEffect, useState } from "react";
import styles from "../../styles/Questions.module.css";
import Login from "../Login";
import arrayShuffle from "array-shuffle";
import { AppContext } from "../helpers/helpers";
import Link from "next/link";
import Solutions from "../solutions";
export default function quiz({ questions }) {
const link = `https://the-trivia-api.com/api/questions`;
const [number, setNumber] = useState(0);
const [quizData, setQuizData] = useState(questions);
const [state, setState] = useState();
const [image, setImage] = useState();
const [numbering, setNumbering] = useState(1);
const [initialRenderComplete, setInitialRenderComplete] = useState(false);
const [chosenOption, setChosenOption] = useState("");
const [showAnswer, setShowAnswer] = useState(false);
const { score, setScore } = useContext(AppContext);
useEffect(() => {
if (localStorage) {
const getNameState = localStorage.getItem("name");
setState(getNameState);
} else {
console.log("errr");
}
}, []);
useEffect(() => {
if (localStorage) {
const getPhotoState = localStorage.getItem("photoUrl");
setImage(getPhotoState);
} else {
console.log("err");
}
}, []);
// Assigning incorrect answer array to oldArray
const oldArray = [
...quizData[number].incorrectAnswers,
quizData[number].correctAnswer,
];
const showAns = (e) => {
e.preventDefault();
setShowAnswer(!showAnswer);
};
// Pushing the correct answer into the incorrect answer array and forming a new array
oldArray.push(quizData[number].correctAnswer);
const newArray = [...new Set(oldArray)];
// Increase the number & index onClick of Next button
const increase = (e) => {
e.preventDefault();
setNumber(number + 1);
setNumbering(numbering + 1);
// checking if correct Answer is in the array then assigning it to getAns
const getAns = newArray.find(
(element) => element === quizData[number].correctAnswer
);
// If the getAns == Whatever You chose increase the score
if (getAns == chosenOption) {
setScore(score + 1);
}
};
// Only for the Finish Quiz Button
const finish = () => {
const getAns = newArray.find(
(element) => element === quizData[number].correctAnswer
);
if (getAns == chosenOption) {
setScore(score + 1);
}
};
const decrease = () => {
setNumber(number - 1);
setNumbering(numbering - 1);
};
// UseEffect to check against Hydration - Important!
useEffect(() => {
setInitialRenderComplete(true);
}, []);
const array = (e) => {
e.preventDefault();
setChosenOption(newArray[1]);
};
if (!initialRenderComplete) {
return null;
} else {
newArray.sort(() => (Math.random() > 0.5 ? 1 : -1)); // Shuffling the New array we pushed the
return (
<div className={styles.container}>
<div className={styles.profile}>
<div className={styles.mainProfile}>
<div className={styles.profilePic}>
<img src={image} alt="img" />
</div>
<h2>{state} </h2>
</div>
</div>
<div className={styles.main}>
<h2>
{numbering}. {questions[number].question}{" "}
</h2>
<div className={styles.list}>
<ul className={styles.list1}>
<div className={styles.flex}>
<h3>A. </h3>
<button onClick={array}>
<li>{newArray[1]} </li>
</button>
</div>
<div className={styles.flex}>
<h3>B. </h3>
<button onClick={() => setChosenOption(newArray[2])}>
{" "}
<li> {newArray[0]} </li>
</button>
</div>
</ul>
<ul className={styles.list2}>
<div className={styles.flexOption}>
<h2>C. </h2>
<button onClick={() => setChosenOption(newArray[0])}>
<li>{newArray[3]}</li>
</button>
</div>
<div className={styles.flexOption}>
<h2>D. </h2>
<button onClick={() => setChosenOption(newArray[3])}>
<li>{newArray[2]} </li>
</button>
</div>
</ul>
</div>
<div className={styles.btnStyle}>
<button onClick={decrease} className={styles.prev}>
Previous{" "}
</button>
{numbering == quizData.length ? (
<Link href="./scores">
<button className={styles.next} onClick={finish}>
{" "}
Finish Quiz{" "}
</button>
</Link>
) : (
<button onClick={increase} className={styles.next}>
Next{" "}
</button>
)}
{showAnswer ? (
<button onClick={showAns} className={styles.next}>
Hide Answer{" "}
</button>
) : (
<button onClick={showAns} className={styles.next}>
See Answer{" "}
</button>
)}
</div>
<p> {showAnswer ? quizData[number].correctAnswer : ""}</p>
</div>
</div>
);
}
}
export const getStaticProps = async () => {
const data = await Axios.get("https://the-trivia-api.com/api/questions");
// const data = req;
const initialData = data.data;
return {
props: {
questions: initialData,
},
};
};
And anytime i console.log the answer i pick, i don't get that option i clicked, So how can i extract the option i clicked on?
const arrayZero = (e) => {
e.preventDefault();
setChosenOption(newArray[0]);
};
const arrayOne = (e) => {
e.preventDefault();
setChosenOption(newArray[1]);
};
return(
//arrayZero being the function
<button onClick={arrayZero}>
<li>{newArray[0]} </li>
</button>
)
e.preventDefault() actually worked, Though it did not stop my array from reshuffling when i click on a button but it made my "chosenOption" state stay the same without changing.

add animation on text and repeat that same animation after every slide

I am learning react and code a function for image slider and change image title with every slide change.
but I want to add any other animation on this text only and repeat that same animation after every slide change.
I don't know how to do it can anyone help me please.
I provide live working demo link for your batter understanding.
https://codesandbox.io/live/a1dd4cecd03
import React, {useEffect, useState} from 'react'
import './Slider.css'
import BtnSlider from './BtnSlider'
import DataSlider from './DataSlider'
export default function Slider() {
const [slideIndex, setSlideIndex] = useState(1)
const nextSlide = () => {
if(slideIndex !== DataSlider.length){
setSlideIndex(slideIndex + 1)
}
else if (slideIndex === DataSlider.length){
setSlideIndex(1)
}
}
const prevSlide = () => {
if(slideIndex !== 1){
setSlideIndex(slideIndex - 1)
}
else if (slideIndex === 1){
setSlideIndex(DataSlider.length)
}
}
useEffect(() => {
const slideInterval = setInterval(() => {
nextSlide()
}, 10000);
return () => clearInterval(slideInterval);
}, [slideIndex]);
const moveDot = index => {
setSlideIndex(index)
}
return (
<div className="container-slider">
{DataSlider.map((obj, index) => {
return (
<div className='bgco'>
<div className='overlay_shadow'></div>
<div key={obj.id} className={slideIndex === index + 1 ? "slide active-anim" : "slide"}>
<div className='slider_name'>
<span>{obj.title}</span>
</div>
<img src={process.env.PUBLIC_URL + `/images/img${index + 1}.jpg`}/>
</div>
</div>
)
})}
<BtnSlider moveSlide={nextSlide} direction={"next"} />
<BtnSlider moveSlide={prevSlide} direction={"prev"}/>
<div className="container-dots">
{Array.from({length: 5}).map((item, index) => (
<div
onClick={() => moveDot(index + 1)}
className={slideIndex === index + 1 ? "dot active" : "dot"}
></div>
))}
</div>
</div>
)
}

How do I make this slideshow react to swiping on a mobile device?

I'm new to React / JS and I've made a slideshow that advances slides by clicking the dots underneath. I would like to add support for swiping on the slideshow on the mobile device because the dots are too small. I've seen some tutorials for this, but they don't seem to play nice with the one I used to make the slideshow. Is this possible using my current setup? How is the most straightforward way to go about this?
import React from 'react';
import './Slideshow.css';
import rmsm1 from './img/RMSMobile1.png';
import rmsm2 from './img/RMSMobile2.png';
import rmsm3 from './img/RMSMobile3.png';
const Slides = [rmsm1, rmsm2, rmsm3];
const delay = 15000;
function RMSMobileSlideshow() {
const [index, setIndex] = React.useState(0);
const timeoutRef = React.useRef(null);
function resetTimeout() {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
}
React.useEffect(() => {resetTimeout();
timeoutRef.current = setTimeout(
() =>
setIndex((prevIndex) =>
prevIndex === Slides.length - 1 ? 0 : prevIndex + 1
),
delay
);
return () => {resetTimeout();};
}, [index]);
return (
<div className="slideshow">
<div className="slideshowSlider"
style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }} >
{Slides.map((imageSource, index) => (
<img
className="slide"
key={index}
src={imageSource}
alt="Slide"
/>
))}
</div>
<div className="slideshowDots">
{Slides.map((_, idx) => (
<div key={idx} className={`slideshowDot${index === idx ? " active" : ""}`} onClick={() => {
setIndex(idx);
}}></div>
))}
</div>
</div>
);
}
export default RMSMobileSlideshow;
I figured out how to do this- I added this code here:
import './Slideshow.css';
import rmsm1 from './img/RMSMobile1.png';
import rmsm2 from './img/RMSMobile2.png';
import rmsm3 from './img/RMSMobile3.png';
import { useState } from "react";
const Slides = [rmsm1, rmsm2, rmsm3];
const delay = 15000;
function RMSMobileSlideshow() {
const [index, setIndex] = React.useState(0);
const timeoutRef = React.useRef(null);
New code starts here:
const [touchPosition, setTouchPosition] = useState(null)
const handleTouchStart = (e) => {
const touchDown = e.touches[0].clientX
setTouchPosition(touchDown)
}
const handleTouchMove = (e) => {
const touchDown = touchPosition
if(touchDown === null) {
return
}
const currentTouch = e.touches[0].clientX
const diff = touchDown - currentTouch
if (diff > 5) {
setIndex((prevIndex) =>
prevIndex === Slides.length - 1 ? 0 : prevIndex + 1
)
}
if (diff < -5) {
setIndex((prevIndex) =>
prevIndex === Slides.length - 1 ? 0 : prevIndex - 1
)
}
setTouchPosition(null)
}
And then I added onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} to the main container like so:
function resetTimeout() {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
}
React.useEffect(() => {resetTimeout();
timeoutRef.current = setTimeout(
() =>
setIndex((prevIndex) =>
prevIndex === Slides.length - 1 ? 0 : prevIndex + 1
),
delay
);
return () => {resetTimeout();};
}, [index]);
return (
<div className="slideshow" onTouchStart={handleTouchStart} onTouchMove={handleTouchMove}>
<div className="slideshowSlider"
style={{ transform: `translate3d(${-index * 100}%, 0, 0)` }} >
{Slides.map((imageSource, index) => (
<img
className="slide"
key={index}
src={imageSource}
alt="Slide"
/>
))}
</div>
<div className="slideshowDots">
{Slides.map((_, idx) => (
<div key={idx} className={`slideshowDot${index === idx ? " active" : ""}`} onClick={() => {
setIndex(idx);
}}></div>
))}
</div>
</div>
);
}
export default RMSMobileSlideshow;

Onclick function only works when I Click twice

I have this Little list that should show different modals based on what the user select , and the problem is When I select the first time it doesn't work and I have to click on it again to work .
Here is my code :
const Mylist = props => {
const [open2, setOpen2] = React.useState(false);
const [open3, setOpen3] = React.useState(false);
const handleClose2 = () => {
setOpen2(false);
};
const handleOpen2 = () => {
setOpen2(true);
};
const handleClose3 = () => {
setOpen3(false);
};
const handleOpen3 = () => {
setOpen3(true);
};
const [isActive , SetIsActive] = useState(false);
const option =["Paid" , "UnPaid"]
return (
<div>
<i class="fas fa-ellipsis-v" onClick={(e) => SetIsActive(!isActive)}></i>
{isActive && (
<div>
{option.map((option) => (
<div
onClick={(e) => {
SetIsActive(false);
{option == 'Paid' && setOpen2(true)}
{option == 'UnPaid' && setOpen3(true)}
}}
>
{option}
</div>
))}
<Modal onClose={handleClose2} open={open2} >
<div>
Content
</div>
</Modal>
<Modal onClose={handleClose3} open={open3} >
<div>
Content
</div>
</Modal>
Your code block is a bit messy with some brackets and closing tags missing (possibly some of the code was not copied in by mistake?).
In any case, I did my best at trying to fill in the missing parts and did some refactoring to your code. I hope that fixes your bug!
import React, { useState } from 'react';
const MyList = (props) => {
const [isOpen1, setIsOpen1] = useState(false);
const [isOpen2, setIsOpen2] = useState(false);
const [isActive, setIsActive] = useState(false);
const openOption = (option) => {
setIsActive(false);
if (option === "Paid") {
setIsOpen1(true);
}
if (option === "UnPaid") {
setIsOpen2(true);
}
};
const options =["Paid", "UnPaid"]
return (
<div>
<i class="fas fa-ellipsis-v" onClick={() => setIsActive(!isActive)}></i>
{isActive && (
<div>
{options.map((option) => (
<div onClick={() => openOption(option)}>
{option}
</div>
))}
</div>
)}
<Modal onClose={() => setIsOpen1(false)} open={isOpen1} >
<div>
Content
</div>
</Modal>
<Modal onClose={() => setIsOpen2(false)} open={isOpen2} >
<div>
Content
</div>
</Modal>
</div>
);
};

Why the wrong element is being updated only when uploading files?

I have built a component CreatePost which is used for creating or editing posts,
the problem is if I render this component twice even if I upload a file from the second component they are changed in the first one, why? Here is the code:
import FileUpload from "#components/form/FileUpload";
import { Attachment, Camera, Video, Writing } from "public/static/icons";
import styles from "#styles/components/Post/CreatePost.module.scss";
import { useSelector } from "react-redux";
import { useInput, useToggle } from "hooks";
import { useRef, useState } from "react";
import StyledButton from "#components/buttons/StyledButton";
import Modal from "#components/Modal";
import { post as postType } from "types/Post";
import Removeable from "#components/Removeable";
interface createPostProps {
submitHandler: (...args) => void;
post?: postType;
isEdit?: boolean;
}
const CreatePost: React.FC<createPostProps> = ({ submitHandler, post = null, isEdit = false }) => {
console.log(post);
const maxFiles = 10;
const [showModal, setShowModal, ref] = useToggle();
const [description, setDescription] = useInput(post?.description || "");
const user = useSelector((state) => state.user);
const [files, setFiles] = useState<any[]>(post?.files || []);
const handleFileUpload = (e) => {
const fileList = Array.from(e.target.files);
if (fileList.length > maxFiles || files.length + fileList.length > maxFiles) {
setShowModal(true);
} else {
const clonedFiles = [...files, ...fileList];
setFiles(clonedFiles);
}
e.target.value = "";
};
const removeHandler = (id) => {
const filtered = files.filter((file) => file.name !== id);
setFiles(filtered);
};
return (
<div className={styles.createPost}>
<div className={styles.top}>
<span>
<img src="/static/images/person1.jpg" />
</span>
<textarea
onChange={setDescription}
className="primaryScrollbar"
aria-multiline={true}
value={description}
placeholder={`What's on your mind ${user?.name?.split(" ")[0]}`}
></textarea>
{description || files.length ? (
<StyledButton
background="bgPrimary"
size="md"
className={styles.submitButton}
onClick={() => {
if (!isEdit)
submitHandler({
files: files,
author: { name: user.name, username: user.username },
postedTime: 52345,
id: Math.random() * Math.random() * 123456789101112,
comments: [],
likes: [],
description,
});
else {
submitHandler({
...post,
description,
files,
});
}
setDescription("");
setFiles([]);
}}
>
{isEdit ? "Edit" : "Post"}
</StyledButton>
) : null}
</div>
<div className={styles.middle}>
<div className={styles.row}>
{files.map((file) => {
return (
<Removeable
key={file.name + Math.random() * 100000}
removeHandler={() => {
removeHandler(file.name);
}}
>
{file.type.includes("image") ? (
<img src={URL.createObjectURL(file)} width={150} height={150} />
) : (
<video>
<source src={URL.createObjectURL(file)} type={file.type} />
</video>
)}
</Removeable>
);
})}
</div>
</div>
<div className={styles.bottom}>
<FileUpload
id="uploadPhoto"
label="upload photo"
icon={
<span>
<Camera /> Photo
</span>
}
className={styles.fileUpload}
multiple
onChange={handleFileUpload}
accept="image/*"
/>
<FileUpload
id="uploadVideo"
label="upload video"
icon={
<span>
<Video /> Video
</span>
}
className={styles.fileUpload}
multiple
onChange={handleFileUpload}
accept="video/*"
/>
<FileUpload
id="writeArticle"
label="write article"
icon={
<span>
<Writing /> Article
</span>
}
className={styles.fileUpload}
multiple
onChange={handleFileUpload}
/>
</div>
{showModal && (
<Modal size="sm" backdrop="transparent" ref={ref} closeModal={setShowModal.bind(null, false)} yPosition="top">
<p>Please choose a maximum of {maxFiles} files</p>
<StyledButton size="md" background="bgPrimary" onClick={setShowModal.bind(null, false)}>
Ok
</StyledButton>
</Modal>
)}
</div>
);
};
export default CreatePost;
Now on my main file I have:
const Main = () => {
const [posts, setPosts] = useState<postType[]>([]);
const addPost = (post: postType) => {
setPosts([post, ...posts]);
};
const editPost = (post: postType) => {
const updated = posts.map((p) => {
if (post.id === post.id) {
p = post;
}
return p;
});
setPosts(updated);
};
const deletePost = (id) => {
const filtered = posts.filter((post) => post.id !== id);
setPosts(filtered);
};
return (
<>
<CreatePost submitHandler={addPost} key="0" />
<CreatePost submitHandler={addPost} key="1"/>
{posts.map((post) => {
return <PostItem {...post} editHandler={editPost} key={post.id} deleteHandler={deletePost.bind(null, post.id)} />;
})}
</>
);
};
export default Main;
I tried to add/remove the key but doesn't change anything, also tried to recreate this problem in a simpler way in sandbox but I can't it works fine there. And the problem is only when I upload files not when I write text inside the <textarea/>
Note: The second in reality is shown dynamically inside a modal when clicked edit in a post, but I just showed it here for simplicity because the same problem occurs in both cases.
Okay after some hours of debugging I finally found the problem.
Because my <FileUpload/> uses id to target the input inside the <CreatePost/> the <FileUpload/> always had same it, so when I used <CreatePost/> more than 1 time it would target the first element that found with that id that's why the first component was being updated

Resources