Компонент не отображается после изменения состояния в функциональном компоненте React - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь создать рекомендованный компонент типа Marquee с помощью React useState, используя массив из другого файла, но мой компонент не будет визуализироваться после изменения массива. Оно должно меняться через каждые 2 секунды.

Мое состояние изменяется правильно в соответствии с журналами моей консоли. Но компонент просто не выполняет рендеринг.

Мои внешние данные выглядят примерно так:

export const testimonials = [
    {
        img     : "",
        info    : "",
        company : "",
        link    : ""
    },
    {
        img     : "",
        info    : "",
        company : "",
        link    : ""
    },...

Не уверен, что это не рендеринг, потому что в общем случае он выглядит так? Это просто предположение, хотя. [объект] [объект] [объект]

const Testimonials = ({ classes }) => {
    const [ arr, setArr ] = useState(testimonials);

    const IncrementTestimonials = (arr2) => {
        let el = arr2.shift();
        arr2.push(el);
        setArr(arr2);
        console.log('changed');
    };

    useEffect(
        () => {
            setInterval(() => {
                console.log('changing');
                IncrementTestimonials(arr);
            }, 2000);
        },
        [ arr ]
    );

    return (
      {arr.map((e) => (
            <div className={classes.Card}>
               <p>"{e.info}"</p>
             </div>
       ))}
    );
};

Любая помощь будет оценена, спасибо.

Ответы [ 4 ]

0 голосов
/ 15 апреля 2020

Попробуйте это:

 const IncrementTestimonials = (arr2) => {
      let el = arr2.shift();
      arr2.push(el);
      setArr(JSON.parse(JSON.stringify(arr2)));
      console.log('changed ' + arr[0].company);
  };
0 голосов
/ 15 апреля 2020

Попробуйте это

const IncrementTestimonials = () => {
        let arr2 = [...arr]
        let el = arr2.shift();
        arr2.push(el);
        setArr(arr2);
        console.log('changed');
    };

 useEffect(
        () => {
            const timer = setTimeout(() => { // use timeout as after every 2 seconds , your effect will run
                console.log('changing');
                IncrementTestimonials();
            }, 2000);
            return ()=>{
               clearTimeout(timer); 
            }
        },
        [ arr ]
    );

    return (
      {arr.map((e) => (
            <div className={classes.Card}>
               <p>{`${e.info}}`</p> // use string interpolation i.e backticks
             </div>
       ))}
    );
0 голосов
/ 15 апреля 2020

arr2 - это просто ссылка на ваше состояние, вы не можете изменить его, вы можете сделать что-то вроде этого:

const IncrementTestimonials = () => {
    const arr2 = [...arr];
    let el = arr2.shift();
    arr2.push(el);
    setArr(arr2);
    console.log('changed');
};
0 голосов
/ 15 апреля 2020

Это плохая практика, чтобы напрямую изменять состояние. Вместо этого вы можете получить первый элемент, если у вас есть arr2.length > 0. Затем, используя .filter(), вы можете удалить первый элемент по индексу. Затем с помощью опции обратного вызова для setState().

Попробуйте сделать следующее:

const IncrementTestimonials = (arr2) => {
    if (arr2.length > 0) {
       const firstElem = arr2[0];

       const filteredArray = arr2.filter((e, i) => i !== 0);

       setArr(prevArr => filteredArray.concat(firstElem));
    }
};

Используя .filter(), вы получите новый массив, см. Из документация:

Метод filter() создает новый массив со всеми элементами, которые проходят тест, реализованный предоставленной функцией.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...