首页 > 解决方案 > 如何将 useEffect 重构为 onlick 函数

问题描述

当用户点击提交按钮时我需要获取,但我绝对不知道该怎么做:

export default function SearchSong() {
    const [topSongs, setTopSongs] = useState([]);
  
    useEffect(() => {
      const fetchData = async () => {
        try {
          const response = await fetch(
            "http://ws.audioscrobbler.com/2.0/?method=track.search&track=Positions&api_key=a3c9fd095f275f4139c33345e78741ed&format=json"
          );
          const data = await response.json();
          setTopSongs(data);
        } catch (error) {
          console.log(error.message);
        }
      };
      fetchData();
    }, []);
  
    return (
      <div>
        <div className="inner-input">
            <h1 className="search">Search for song:
            <input size="50" type="text"/>
            <button type="submit"></button>
            </h1>
        </div>
        {topSongs?.results?.trackmatches?.track.length &&
          topSongs.results.trackmatches.track.map((datumn) => {
            return (
              <Fragment key={datumn.name}>
                              <h1 className='heading'>{datumn.name}</h1>
              </Fragment>
            );
          })}
      </div>
    )
  }

我可以用类组件来做,但不是功能性的

标签: reactjscomponentsrefactoringuse-effect

解决方案


您可以创建一个名为的新状态fetchSongs,该状态将在Fetch Songs按下按钮时切换,并将该状态作为依赖项添加到 中useEffect,因此每次单击Fetch Songs按钮时,状态fetchSongs更改都会触发useEffect.

@sonkatamas 给出的答案也是一个不错的答案。但它不会在组件首次加载时运行 fetch 功能,在这种情况下useEffect就派上用场了。

export default function SearchSong() {
    const [topSongs, setTopSongs] = useState([]);
    const [fetchSongs, setFetchSongs] = useState(false);
  
    useEffect(() => {
      const fetchData = async () => {
        try {
          const response = await fetch(
            "http://ws.audioscrobbler.com/2.0/?method=track.search&track=Positions&api_key=a3c9fd095f275f4139c33345e78741ed&format=json"
          );
          const data = await response.json();
          setTopSongs(data);
        } catch (error) {
          console.log(error.message);
        }
      };
      fetchData();
    }, [fetchSongs]);
  
    return (
      <div>
        <div className="inner-input">
            <h1 className="search">Search for song:
            <input size="50" type="text"/>
            <button onClick={()=> setFetchSongs(!fetchSongs)}>Fetch Songs</button>
            </h1>
        </div>
        {topSongs?.results?.trackmatches?.track.length &&
          topSongs.results.trackmatches.track.map((datumn) => {
            return (
              <Fragment key={datumn.name}>
                              <h1 className='heading'>{datumn.name}</h1>
              </Fragment>
            );
          })}
      </div>
    )
  }


推荐阅读