【问题标题】:Component not re rendering after state changing in React functional componentReact 功能组件中状态更改后组件未重新渲染
【发布时间】:2020-07-28 15:56:15
【问题描述】:

我正在尝试使用来自另一个文件的数组创建一个带有 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>
       ))}
    );
};

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

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    arr2 只是对你的状态的引用,你不能修改它,你可以这样做:

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

    【讨论】:

      【解决方案2】:

      直接修改状态是不好的做法。相反,如果你有arr2.length &gt; 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() 方法创建一个新数组,其中包含所有通过所提供函数实现的测试的元素。

      我希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        试试这个

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

        【讨论】:

          【解决方案4】:

          试试这个:

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

          【讨论】:

          • 我最初的推荐数组是一个对象数组,这有关系吗?
          • 不是真的,只是想知道您是在尝试动态获取推荐还是已经预先填充。
          • 是的,它们都预先填充在另一个文件中。
          • 刚刚更新了我的评论,这个改动会强制数组更新数组。突变是数组的问题
          【解决方案5】:

          【讨论】:

          • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
          猜你喜欢
          • 2021-07-25
          • 2021-12-22
          • 2020-04-07
          • 2020-05-04
          • 1970-01-01
          • 2018-04-20
          • 1970-01-01
          • 2021-05-19
          • 2022-01-26
          相关资源
          最近更新 更多