简体   繁体   中英

useState no rerendering

Can someone help me figure out how come when I change my state using ReactHooks its not rerendering my component

   const [newsCatalog, setNewsCatalog] = useState([]);
    useEffect(() => {
     fetchNews();
    });

    const fetchNews = async () => {
      const GetAllNewArticleResults = await GetAllNewArticle();
      let promises = [];
            let tempNewsCatalog = newsCatalog;
            GetAllNewArticleResults.map(async e => {
              promises.push(
                await htmlToJson.parse(
                  e.HTMLNewsCode,
                  {
                    title: function($doc) {
                      return textTruncate($doc.find("H2").text(), 50);
                    },
                    link: function($doc) {
                      return $doc.find("A").attr("href");
                    },
                    content: function($doc) {
                      return textTruncate($doc.find("P").text(), 80);
                    },
                    imageURL: function($doc) {
                      return $doc.find("img").attr("src");
                    }
                  },
                  function(err, result) {
                    tempNewsCatalog.push({
                      ...result
                    });
                  }
                )
              );
              return null;
     });

    Promise.all(promises).then(() => {
      setNewsCatalog(newsCatalog, ...tempNewsCatalog);    
    }); 
};


          return (
            <div className="container mb-4" id="News">
              <div className="h4 mb-3">OUR NEWS</div>
              <div className="d-flex justify-content-between flex-wrap mw-90">
                {newsCatalog.length}
              </div>
            </div>
          );

When I tried running it, the just displays "0" in the "newsCatalog.length". But when I tried to inspect it, it already has items on it.

// helper method
function htmlToJson(htmlNewsCode) {
 return new Promise((resolve, reject) => {
   htmlToJson.parse(
     htmlNewsCode,
     {
       title: function($doc) { return textTruncate($doc.find("H2").text(), 50); },
       // implement your other methods
     },
     (err, result) => { 
       if (err) { 
        reject(err);
        return;
       }

       resolve(result)
     }
   )
 })
}


// your component
const [newsCatalog, setNewsCatalog] = React.useState([]);

React.useEffect(() => {

 async function fetchNews() {
  // TODO: Implement error handling using try/catch
  const GetAllNewArticleResults = await GetAllNewArticle();
  const promises = GetAllNewArticleResults.map((e) => {
   return htmlToJson(e. HTMLNewsCode);
  })

  const results = await Promise.all(promises);
  setNewsCatalog(prev => [...prev, ...results]);
 }

 fetchNews();

}, /* You probably need to specify the DEPS */)

Probably your Promise.all call failed, and issue is with this code

tempNewsCatalog.push({
   ...result
});

It is pushing to newsCatalog . Because it is object and connect by pointer with tempNewsCatalog . So you have values, but no rerender.

try instead to create epmty array, and push it there

Thanks for AngelSalazar I tried changing my code

const [newsCatalog, setNewsCatalog] = useState([]);

React.useEffect(() => {
  async function fetchNews() {
          // TODO: Implement error handling using try/catch
    const GetAllNewArticleResults = await GetAllNewArticle();
    let promises = [];

    GetAllNewArticleResults.map(e => {
      promises.push(
        htmlToJson.parse(
                e.HTMLNewsCode,
                {
                  title: function($doc) {
                    return textTruncate($doc.find("H2").text(), 50);
                  },
                  link: function($doc) {
                    return $doc.find("A").attr("href");
                  },
                  content: function($doc) {
                    return textTruncate($doc.find("P").text(), 80);
                  },
                  imageURL: function($doc) {
                    return $doc.find("img").attr("src");
                  }
                },
                function(err, result) {
                  return result;
                }
              )
            );
          });

          const results = await Promise.all(promises);
          setNewsCatalog(prev => [...prev, ...results]);
     }

   fetchNews();
 }, []);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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