Home > Mobile >  How can I shuffle an array of objects on page render and map over the shuffled array without console
How can I shuffle an array of objects on page render and map over the shuffled array without console

Time:01-16

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;
}
  •  Tags:  
  • Related