0

Intro

As the title states, I'm trying to figure out why a certain function, when called, gets repeatedly called multiple times.

Details

When the application first loads, images are displayed with the help of useEffect(), which is the desired behavior.

There is a search input box that is used to search for images. When an image is searched, two functions are invoked onChange() and onSearch(), which calls the setToken() and handleSelectToken() functions respectively.

I was debugging the application using Chrome, and it looks like the handleSelectionToken() along with the other functions are being called multiple times. I think the useEffect() function may be the issue, but I'm not very certain.

How can I fix this issue?

  function getHomePage() {
  const [token, setToken] = useState("");
  const [visibility, setVisibility] = useState(false);
  const [NFTBalances, setNFTBalances] = useState();
  const [collection, setCollection] = useState();
  const [nft, setNft] = useState();
  const { Moralis } = useMoralis();

  //load my images when application starts
  useEffect(() =>  {
    collectionChanged('myCollection')
  })
    
const handleSelectToken = async (num, col) => {
    if (num && col) {
      const dbNFTs = Moralis.Object.extend(col);
      const query = new Moralis.Query(dbNFTs);
      console.log(num);
      query.equalTo("tokenId", num);
      let selectedNFT = await query.first();
      selectedNFT = selectedNFT.attributes;
      console.log(selectedNFT);
      setNft(selectedNFT);
      setVisibility(true);

      //open modal
      $("#openModal").modal("show");
    }
  };


  const addToNFTs = async (col) => {
    const dbNFTs = Moralis.Object.extend(col);
    const query = new Moralis.Query(dbNFTs);
    query.ascending("rank");
    query.limit(4);
    const topNFTs = query.skip(NFTBalances.length);
    const results = await topNFTs.find();
    setNFTBalances(NFTBalances.concat(results));
  }

return (
  <>
//modal box
      <div className="modal fade" id="openModal" tabIndex="-1" role="dialog" aria-hidden="true">
           <div className="modal-dialog modal-lg" role="document">
              <div className="modal-content">
                 <div className="modal-header">
                    <button type="button" className="close" 
                         data-dismiss="modal" aria-label="Close">
                       <span aria-hidden="true">&times;</span>
                    </button>
                 </div>
                 <div className="modal-body">
                   <div>
                     <Image preview={false} src={path_to_image} loading="lazy"
                         style={{ display: "block", width: "50%"}}/>                               
                   </div>
                 </div>
              </div>
           </div>
     </div>

 
               <div className="col-xxl-3 col-xl-3 col-lg-3 col-md-3">
                    <div className="filter-sidebar">
                       <div className="filter-sidebar-content">
                          <div className="form-group">

                             //SEARCH BOX
                             <Search placeholder="Please search here"
                                   onChange={(e) => setToken(e.target.value) }
                                   onSearch={() => handleSelectToken(token, collection)} />
                          </div>
                       </div>
                    </div>
                 </div>

          
  </>        
);
}

export default getHomePage;
David Scholz
  • 8,421
  • 12
  • 19
  • 34
  • 3
    You haven't provided a dependency array to your useEffect, so it runs on every render. If you only want it to run on first mount pass an empty dependency array. `useEffect(() => { collectionChanged('myCollection') }, [])` see: [React: useEffect](https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects) – pilchard Apr 16 '22 at 01:11
  • 1
    the above comment is correct. See https://reactjs.org/docs/hooks-effect.html – Abe Apr 16 '22 at 01:13
  • 1
    Does this answer your question? [How to call loading function with React useEffect only once](https://stackoverflow.com/questions/53120972/how-to-call-loading-function-with-react-useeffect-only-once) – pilchard Apr 16 '22 at 01:16

1 Answers1

0
useEffect(() =>  {
    collectionChanged('myCollection')
  }, [])

This will fix your problem. Check please. The above comment is correct.