I have got this UI below. When I first open this component ModalColorList
and click goNext()
, it does not go next at first but the second time. After that, it goes next well, so it means the user needs to click twice the button in order to go next.
In the case of goPrev()
it works fine, but it does not seem to be clean either.
I usually google before beginning to code, but this time, I would like to try by myself, so maybe this does not work as expected. Please let me know the better way to make goPrev
and goNext
smoother.
ModalColorList
const ModalColorList = ({ data }) => {
const [isLoading, setIsLoading] = useState(false);
const [large, setLarge] = useState({
idx: data?.index,
name: data?.name,
src: data?.image,
});
const onColorClick = (color, idx) => {
setLarge({
idx,
name: color.node.name,
src: color.node.imageAttribute.image.mediaItemUrl,
});
};
const goPrev = () => {
let count = 0;
if (large.idx === 0) {
count = data.data.length - 1;
} else {
count = large.idx - 1;
}
setLarge({
idx: count,
name: data?.data[count]?.node.name,
src: data?.data[count]?.node.imageAttribute.image.mediaItemUrl,
});
};
const goNext = () => {
let count = data.index ;
if (data.index > data.data.length) {
data.index = 0;
count = 0;
}
setLarge({
idx: count,
name: data?.data[count]?.node.name,
src: data?.data[count]?.node.imageAttribute.image.mediaItemUrl,
});
};
useEffect(() => {
setIsLoading(true);
}, []);
return (
<>
{isLoading && (
<div >
<div>
<div onClick={goPrev}>
<RiArrowLeftSLine />
</div>
<div>
<Image src={large.src} objectFit="cover" />
</div>
<div className="icon-wrap -right-[50px]" onClick={goNext}>
<RiArrowRightSLine />
</div>
</div>
<ul>
{data.data.map((color, idx) => (
<li key={color.node.id} onClick={() => onColorClick(color, idx)} >
<div className={` ${large.idx === idx && 'border-[#f7941d] border-4'}`}>
<Image src={color.node.imageAttribute.image.mediaItemUrl} />
</div>
</li>
))}
</ul>
</div>
)}
</>
);
};
export default ModalColorList;
Kindly let me
CodePudding user response:
I'm not sure why didn't things didn't work for you, as there was very little code that I could analysis. But till what you have shared, the component should have been working properly.
I have cleaned your work some what and create a codesandbox for the same, hope it gives you some idea.
If this doesn't help, please do share a codesandbox instance where the behavior is reproduceable I will check on it.
ModalColorList.js
import { useState, useEffect } from "react";
const ModalColorList = ({ data }) => {
const [isLoading, setIsLoading] = useState(true);
const [large, setLarge] = useState({
idx: data?.index,
name: data?.name,
src: data?.image
});
const onColorClick = (color, idx) => {
setLarge({
idx,
name: color.name,
src: color.src
});
};
const goPrev = () => {
let count = 0;
const collection = data.collection;
if (large.idx === 0) {
count = collection.length - 1;
} else {
count = large.idx - 1;
}
setLarge({
idx: count,
name: collection[count].name,
src: collection[count].src
});
};
const goNext = () => {
let count = 0;
const collection = data.collection;
if (large.idx 1 >= collection.length) {
count = 0;
} else {
count = large.idx 1;
}
console.log(collection, count);
setLarge({
idx: count,
name: collection[count].name,
src: collection[count].src
});
};
return (
<>
{isLoading && (
<div>
<div>
<div onClick={goPrev}>Left</div>
<div onClick={goNext}>Right</div>
<div>
<img src={large.src} objectFit="cover" />
</div>
</div>
<ul>
{data.collection.map((color, idx) => (
<li key={idx} onClick={() => onColorClick(color, idx)}>
<div
className={` ${
large.idx === idx && "border-[#f7941d] border-4"
}`}
>
<img src={color.src} />
</div>
</li>
))}
</ul>
</div>
)}
</>
);
};
export default ModalColorList;
colorSample.js
export default {
name: "glassy",
src:
"https://images.unsplash.com/photo-1604079628040-94301bb21b91?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80",
index: 0,
collection: [
{
name: "glassy",
src:
"https://images.unsplash.com/photo-1604079628040-94301bb21b91?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
},
{
name: "pop",
src:
"https://images.unsplash.com/photo-1498940757830-82f7813bf178?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1074&q=80"
},
{
name: "milky",
src:
"https://images.unsplash.com/photo-1556139943-4bdca53adf1e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80"
}
]
};
App.js
import "./styles.css";
import ModalColorList from "./ModalColorList";
import colorSample from "./colorSample";
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<ModalColorList data={colorSample} />
</div>
);
}
CodePudding user response:
if you understand you have list and want to navigate with next and pre, simple you can create temp array, use push and pop to add and remove items then always show the last item like that.
yourArray[yourArray.length - 1]
let me show you example.
let currentIndex = 0;
const mylistItem = [1,2,3,4,5];
let showItems = [mylistItem[currentIndex]] // default show first item always showing last item
const lastItem = showItems[showItems.length - 1]; // the item want to display
for Moving forward
showItems.push(myListItem[currentIndex 1]);
currentIndex = 1;
for Moving back
showItems.pop();
currentIndex -= 1;