简体   繁体   English

作为参数传递的 React.js useState 函数不会重新渲染其组件

[英]React.js useState function passed as a parameter doesn't rerender its component

So what I'm trying to do is to have a component that renders a list of games.所以我想要做的是拥有一个呈现游戏列表的组件。

The component calls the function ApiMMO.getGamesFromTo() from a separate script passing the (response)=>{setGameList(response)} as a parameter.该组件从传递(response)=>{setGameList(response)}作为参数的单独脚本调用函数ApiMMO.getGamesFromTo() This separated scripts does a request and uses the function passed as parameter to change the component's state.这个分离的脚本执行请求并使用作为参数传递的函数来更改组件的状态。 The script does the job and the console logs confirm that the gameList changed but the component doesn't rerender.脚本完成工作,控制台日志确认gameList更改,但组件未重新渲染。

The way I know the component didn't rerender is because the GameCard component prints its props when mounted.我知道组件没有重新渲染的方式是因为GameCard组件在安装时打印了它的道具。

So here's the code:所以这是代码:

function GameLibrary(){
    const [gameList, setGameList] = React.useState([]);
    const [gamesPerPage, setGamesPerPage] = React.useState(20);
    const [pageIndex, setPageIndex] = React.useState(1);

    // setgameList(ApiMMO.getGamesFromTo( gamesPerPage, pageIndex))

    React.useEffect(() => {
        ApiMMO.getGamesFromTo( gamesPerPage, pageIndex, ((response)=>{setGameList(response)}))
      }, [])

    React.useEffect(()=> {
        console.log('gameList changed: ');
        console.log(gameList);
    },[gameList])

    return(
        <div>
            { gameList.length > 0 ? (
                gameList.map(item => {
                <GameCard game={item}/>
            })) : (
                <GameCard game={'no prop'}/>
            ) }
        </div>
    );
}

EDIT:编辑:

Here's the ApiMMO.getGamesFromTo() code:这是ApiMMO.getGamesFromTo()代码:

function getGamesFromTo(numPerPage, page, callback){
    let options = {
        method: 'GET',
        url: 'https://mmo-games.p.rapidapi.com/games',
        headers: {
          'x-rapidapi-host': 'mmo-games.p.rapidapi.com',
          'x-rapidapi-key': rapidapiUserKey
        }
      };

    axios.request(options).then(function (response) {

        let from = (page - 1) * numPerPage;
        let to = page * numPerPage;
        let pageArray = response.data.slice(from, to)
        console.log("REQUEST RESULT: " + pageArray)
        callback(pageArray)
        return pageArray;

    }).catch(function (error) {
        console.error(error);
    });
}

Can you change getGamesFromTo() so it doesn't need the callback and just returns the response?您可以更改getGamesFromTo()以便它不需要回调而只返回响应吗?

Then in your useEffect you could just have:然后在您的 useEffect 中,您可以拥有:

React.useEffect(() => {
  const getGames = async () => await ApiMMO.getGamesFromTo(gamesPerPage, pageIndex)
  setGameList(getGames())
}, [setGameList, gamesPerPage, pageIndex])

-edit- Updated the answer to add an async function inside useEffect so my answer should now work. -edit- 更新了在 useEffect 中添加异步函数的答案,所以我的答案现在应该可以工作了。

You have to return some value on the map, or else remove the braces {}您必须在地图上返回一些值,否则删除大括号{}

Replace this:替换这个:

return(
        <div>
            { gameList.length > 0 ? (
                gameList.map(item => {
                <GameCard game={item}/>
            })) : (
                <GameCard game={'no prop'}/>
            ) }
        </div>
    );

By this:这样:

return(
    <div>
        { gameList.length > 0 ? (
            gameList.map(item => 
             <GameCard game={item}/>
        )) : (
            <GameCard game={'no prop'}/>
        ) }
    </div>
    );

Or this:或这个:

return(
        <div>
            { gameList.length > 0 ? (
                gameList.map(item => {
                 return <GameCard game={item}/>
            })) : (
                <GameCard game={'no prop'}/>
            ) }
        </div>
        );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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