I can shuffle the array and map over it. My application correctly displays the shuffled data (translate3d for a slider effect). However, I get a perpetually growing list of console warnings:
"Encountered two children with the same key, "13". Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version."
How should this be written to handle the warnings?
.wrapper{
position: relative;
width: 100%;
height: 86.5vh;
overflow: hidden;
}
.slider{
display: flex;
width: 100vw;
height: 89vh;
}
.slides{
display: flex;
width: 4000vw;
height: 88.75vh;
transition: ease 1000ms;
}
.slide{
width: 100vw;
height: 89vh;
object-fit: fill;
}
.wrapperTest{
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 55%;
transition: ease-out 1000ms;
}
.sliderTest{
display: flex;
align-items: center;
justify-content: center;
height: 35vh;
}
.slidesTest{
display: flex;
align-items: center;
justify-content: center;
width: 4000vw;
height: 35vh;
}
.slideWrapper{
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
}
.slideContent{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 92vw;
height: 28vh;
border-radius: 22px;
background-color: rgba(0,0,0,.55);
}
.testimoneyWrapper{
display: flex;
align-items: top;
justify-content: space-between;
overflow: hidden;
}
.leftQuote{
font-size: 7.5vw;
margin: 0px 0px 0px 8px;
color: white;
}
.rightQuote{
font-size: 7.5vw;
margin: 0px 8px 0px 0px;
color: white;
}
.slideTestimoneyWrapper{
display: flex;
align-items: center;
justify-content: center;
}
.slideTestimoney{
display: flex;
width: 90%;
margin: 10px 0px 6px 0px;
font-size: 3.2vw;
font-family: 'PT Sans', sans-serif;
text-align: center;
color: white;
}
.slideInfos{
display: flex;
align-items: center;
justify-content: center;
font-size: 2.8vw;
font-family: 'PT Sans';
font-weight: 500;
color: white;
}
.slideName{
margin-right: 40px;
}
.slideInfo{
display: flex;
align-items: center;
justify-content: center;
}
.slideInfo1{
color: #0099CC;
}
.slideInfo2{
color: #EA4335;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
const scrollImages = [
{
id: 1,
img: photo1,
},
{
id: 2,
img: photo2,
},
{
id: 3,
img: photo3,
},
]
const HomeScroll = () => {
function shuffleArray(array) {
var i, j, temp;
for (i = array.length -1; i > 0; i--) {
j = Math.floor(Math.random() * i);
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
const [id, setId] = useState(0)
const delay = 10000;
useEffect(() => {
shuffleArray(scrollTestimonials)
setTimeout(() =>
setId((prevIndex) =>
prevIndex === scrollImages.length - 1 ? 0 : prevIndex 1
),
delay
);
return () => {};
}, [id]);
return (
<div className="wrapper">
<div className="slider">
<div className="slides"
style={{ transform: `translate3d(${-id * 2.5}%, 0, 0)` }}
>
{scrollImages?.map((item) => (
<div className="widthWide" key={item.id}>
<img className="slide" src={item.img} key={item.id} alt="Slide" />
</div>
))}
<div className="wrapperTest">
<div className="sliderTest">
<div className="slidesTest">
{scrollTestimonials?.map((item) => (
<div className="slideWrapper" key={item.id} >
<div className="slideContent" key={item.id} >
<div className="testimoneyWrapper" key={item.id} >
<FontAwesomeIcon icon={faQuoteLeft} className="leftQuote" key={item.id} />
<div className="slideTestimoneyWrapper">
<p className="slideTestimoney" key={item.id}>{item.text}</p>
</div>
<FontAwesomeIcon icon={faQuoteRight} className="rightQuote" key={item.id} />
</div>
<div className="slideInfos" key={item.id} >
<p className="slideName" key={item.id}>{item.name}</p>
<div className="slideInfo" key={item.id}>
{item.site === "Yelp" ?
<>
<FontAwesomeIcon icon={faYelp} size="2x" color="#0099CC" key={item.id} />
<p className="slideInfo1" key={item.id}>Yelp</p>
</>
:
<>
<FontAwesomeIcon icon={faGoogle} size="1x" color="#EA4335" key={item.id} />
<p className="slideInfo2" key={item.id}>oogle</p>
</>
}
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
</div>
)
}
CodePudding user response:
in JS, you could use the library of Lodash, that has a function .shuffle(collection). Then use the shuffled data as model of your view.
CodePudding user response:
You could try to shuffle your array like this:
function shuffleArray(array) {
return array.sort(function () {
return Math.random() - 0.5;
});
}
EDIT: You also should create a new object/array after shuffling. Otherwise React will not detect any change.
EDIT 2: Slightly improved implementation of your shuffle function:
function shuffleArray(array) {
const newArray = [ ...array ];
for (let i = newArray.length - 1; i > 0; --i) {
const j = Math.floor(Math.random() * i);
const temp = newArray[i];
newArray[i] = newArray[j];
newArray[j] = temp;
}
return newArray;
}
