繁体   English   中英

在 React 功能组件中更改 state 后组件未重新渲染

[英]Component not re rendering after state changing in React functional component

我试图使用来自另一个文件的数组创建一个带有 React useState 的推荐选框类型组件,但我的组件在更改数组后不会重新呈现。 它应该每 2 秒更改一次。

根据我的控制台日志,我的 state 正在正确更改。 但是组件只是没有重新渲染。

我的外部数据如下所示:

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>
       ))}
    );
};

任何帮助将不胜感激,谢谢。

arr2 只是对您的 state 的引用,您无法修改它,您可以执行以下操作:

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

直接修改 state 是一种不好的做法。 相反,如果您有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()方法创建一个新数组,其中包含通过提供的 function 实现的测试的所有元素。

我希望这有帮助!

尝试这个

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>
       ))}
    );

尝试这个:

 const IncrementTestimonials = (arr2) => {
      let el = arr2.shift();
      arr2.push(el);
      setArr(JSON.parse(JSON.stringify(arr2)));
      console.log('changed ' + arr[0].company);
  };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM