【问题标题】:usestate react hook for functional component always rerender whole component while using setstate功能组件的 usestate 反应钩子总是在使用 setstate 时重新渲染整个组件
【发布时间】:2020-05-25 11:29:11
【问题描述】:

每当我设置新状态时,我都会在功能组件中使用 usestate reacthooks 我的问题 整个组件重新渲染,我的状态恢复到初始状态

const Feeds = (props) => {
  // remove the intial element that is of no use...
  const baseUrl = props.api
  let nextPage = props.feeds.nextPage;
  let products = props.feeds.products.filter(el => !el.isSilder);
  console.log('intial products ....', products);

  let [feeds,setFeeds] = useState(products);
  let waitForNextTrench = false;  

  const feedRequestData =  {
    filterData: {
      catArray:[],
      assured:"0",
      gender:"NA",
      cityId:"NA"
    },
    pageNo: nextPage
  };
  useEffect(()=>{
    window.addEventListener("scroll",handleScroll);
    return () => {
        window.removeEventListener("scroll", handleScroll);
    };
  },[])

  const handleScroll = () => {
    const loadMore = document.getElementById("loadMore");
        if (loadMore && shared.isElementVisible(loadMore)) {
      loadMoreFeeds();
        }
  };

  const loadMoreFeeds = () => {
    if (nextPage != 1) {
      return null;
    }
    if (waitForNextTrench) {
      return null;
    }
    waitForNextTrench = true // make the function wait till the data is 
  renderd properly

    feedsApi.userFeeds(baseUrl+'/product/userFeeds',feedRequestData).then(data=>{
      if (data.success) {
        const updatedFeeds = products.concat(data.products.filter(el => !el.isSilder));
        setFeeds(updatedFeeds);


        console.log('this is the feeds', feeds.length);

        nextPage = data.nextPage;
        waitForNextTrench = false;
      }else { 
        // lets handle error later
        waitForNextTrench = true;
      }
    }).catch(err=>{
        // let me handle error later    
    })    
  }
  const headObject = {
    title:'Buy Sell fashion / electronics / tickets / books / online – coutloot.com", "Best platform to sell | buy products online, women\'s and men\'s clothes, ethnic, mobile phones, beauty/makeup, books, footwear, bags, electronics, shows, events tickets online in india',
    desc : "",
    keywords:""
  }
   return(
       <Fragment>
            <Header headobject={headObject}/>
            <div className={`d-flex f22 ${styles.feedheader}`}> 
              <a className="icon-hamberger_menu py-2-5 pl-3 text-pink1"></a>
              <div className="d-flex align-items-center text-black pl-3 w67">
                        <span className="f16 font-bold px-2"> Filters </span>  
                        <img src="/assets/images/go-forward-arrow.png" alt="" height="15px" width="15px" />
                    </div>
              <div className="d-flex">
                <div className="text-center py-2 px-2 r-icon">
                    <span className="icon-search ml-auto" ></span>
                </div>
                <div className="text-center py-2 px-2 r-icon">
                    <a className="icon-wishlist" ></a>
                </div>
                <div className="text-center py-2 px-2 r-icon position-relative">
                    <a className="icon-shopping-cart" ></a>
                    <span className={`${styles.cartCount}`}> 1</span>
                </div>
              </div>
            </div>
            <Layout >
              {
                <FeedController feeds={feeds} />

              }              
            </Layout>
            <LoadMore />
       </Fragment>
   )
}

我想在设置状态下推送新数组,但它每次都在渲染并且状态变为初始值

初始值是数组列表,我想连接从 API 加载获得的新数组列表,当用户滚动到屏幕底部时会调用更多提要

现在我已经给出了完整的组件代码

我只想更新 dom 而不是整个函数

【问题讨论】:

  • 可以分享一下整个组件代码吗?
  • @AhmedAbdulrahman 这是非常冗长的代码,我刚刚分享了导致主要问题的小型 sn-ps
  • 了解 loadMoreFeeds 的调用方式很重要。你也写过调用 setFeeds 的 useEffect 吗?
  • @ShubhamKhatri 当屏幕滚动到下方时
  • @ShubhamKhatri 请立即查看

标签: javascript reactjs


【解决方案1】:

尝试将函数包装在useEffect hook 中,它允许处理组件生命周期方法

useEffect(()=>{
  feedsApi.userFeeds(baseUrl+'/product/userFeeds',feedRequestData).then(data=>{
    if (data.success) {
      const updatedFeeds = products.concat(data.products.filter(el => !el.isSilder));
      setFeeds(updatedFeeds);

      nextPage = data.nextPage;
      waitForNextTrench = false;

    }else { 
      // lets handle error later
      waitForNextTrench = true;
    }
  }).catch(err=>{
    // let me handle error later    
  })    
}, [])

【讨论】:

  • hi react hooks 只允许在 react 功能组件内部
【解决方案2】:

我更深入地检查了你的代码,我想我发现了问题:你依赖products 来更新状态,但products 是每次渲染的一个新变量。使用useState 的原因是React 将确保在重新渲染之间保持此状态。我希望它能解决您的问题。

const Feeds = props => {
  // remove the intial element that is of no use...
  const baseUrl = props.api;
  let nextPage = props.feeds.nextPage;
  let products = props.feeds.products.filter(el => !el.isSilder);
  console.log("intial products ....", products);

  let [feeds, setFeeds] = useState(products);

  let waitForNextTrench = false;

  const feedRequestData = {
     filterData: {
       catArray: [],
       assured: "0",
       gender: "NA",
       cityId: "NA"
     },
     pageNo: nextPage
   };

  const loadMoreFeeds = () => {
    if (nextPage === 1 || !waitForNextTrench) {
      waitForNextTrench = true; // make the function wait till the data is renderd properly

      feedsApi
        .userFeeds(baseUrl + "/product/userFeeds", feedRequestData)
        .then(data => {
          if (data.success) {
            const updatedFeeds = feeds.concat(  // This was the important change!!!
              data.products.filter(el => !el.isSilder)
            );
            setFeeds(updatedFeeds);

            console.log("this is the feeds", feeds.length);

            nextPage = data.nextPage;
            waitForNextTrench = false;
          } else {
            // lets handle error later
            waitForNextTrench = true;
          }
        })
        .catch(err => {
          // let me handle error later
        });
    }
  };

  const handleScroll = () => {
    const loadMore = document.getElementById("loadMore");
    if (loadMore && shared.isElementVisible(loadMore)) {
      loadMoreFeeds();
    }
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  const headObject = {
    title:
      "Buy Sell fashion / electronics / tickets / books / online – coutloot.com\", \"Best platform to sell | buy products online, women's and men's clothes, ethnic, mobile phones, beauty/makeup, books, footwear, bags, electronics, shows, events tickets online in india",
    desc: "",
    keywords: ""
  };

  return (
    <Fragment>
      <Header headobject={headObject} />
      <div className={`d-flex f22 ${styles.feedheader}`}>
        <a className="icon-hamberger_menu py-2-5 pl-3 text-pink1"></a>
        <div className="d-flex align-items-center text-black pl-3 w67">
          <span className="f16 font-bold px-2"> Filters </span>
          <img
            src="/assets/images/go-forward-arrow.png"
            alt=""
            height="15px"
            width="15px"
          />
        </div>
        <div className="d-flex">
          <div className="text-center py-2 px-2 r-icon">
            <span className="icon-search ml-auto"></span>
          </div>
          <div className="text-center py-2 px-2 r-icon">
            <a className="icon-wishlist"></a>
          </div>
          <div className="text-center py-2 px-2 r-icon position-relative">
            <a className="icon-shopping-cart"></a>
            <span className={`${styles.cartCount}`}> 1</span>
          </div>
        </div>
      </div>
      <Layout>{<FeedController feeds={feeds} />}</Layout>
      <LoadMore />
    </Fragment>
  );
};

另外,我建议您使用 eslint 并再次查看文档,它们总能带来洞察力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-07
    • 2019-07-27
    • 2020-08-03
    • 2020-03-27
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    相关资源
    最近更新 更多