typescript NextJs with React +无法更新父状态值

ffvjumwh  于 2023-06-30  发布在  TypeScript
关注(0)|答案(2)|浏览(123)

我是NextJS的新手,正在使用NextJS和React。所以我使用trpc和useQuery获取用户列表。
然后我根据用户名过滤用户列表。我已经添加了示例代码,但我有更多的逻辑。
在下面的代码中,当我点击按钮时,我传递了用户名,如“user1”,在父组件(Users.tsx)中,方法updateFilter触发并获取用户的值。在此方法中,我试图使用用户对象设置setUsersData值。我得到了错误。有人能帮我解决这个问题吗?
Users.tsx

const Page = () => {    
    const users = trpc.users.getUsersSummary.useQuery(
        {},
        {
            onError(err) {
                console.log('Failed to retrieve users summary')
            },
        },
    );
    const [usersData, setUsersData] = useState(users);

    const filteredLists = (username: string) => {       
        return users?.data?.users.filter((user: any) =>{
            user.name === username;
        });
    }

    const updateFilter = (username: string) => {
        const getFilterQuery = filteredLists(username);

        setUsersData(current => {
            const data = {...current.data};
            data.users = getFilterQuery;
            return {...current, data};          
        });
    };

    return (
        <div>
            <UserList setUserType={updateFilter} usersSummary={usersData.data} />
        </div>
    )

}

Userslists.tsx

// Global
import { useEffect } from 'react';

export const UserList = ({ usersSummary, setUserType }: UserFilterPropTypes) => {
    const items = usersSummary?.users

    const handleChange = () => {
        setUserType("user1")
    }

    return (
        <div>
        <button onclick= { handleChange()> Filter < /button>
        //Iterating the data
        < /div>
    )
}

Json从响应中获取:

[
    {
        "result": {
            "data": {
                "json": {
                    "totalUsers": 40,
                    "users": [
                        {
                            "name": "user1",
                            "status": "Active"
                        },
                        {
                            "name": "user2",
                            "status": "De Active"
                        },
                        {
                            "name": "user3",
                            "status": "Active"
                        },
                        {
                            "name": "user4",
                            "status": "De Active"
                        },
                        {
                            "name": "user5",
                            "status": "Active"
                        },
                    ]
                }
            }
        
        }
    }
]

错误详细信息:
类型“”的参数(当前:(QueryObserverRefetchErrorResult

ffscu2ro

ffscu2ro1#

注意<button onclick= { handleChange()> Filter < /button>代码。onclick处理程序必须是onclick={handleChange}
这样,当onclick事件发生时,handleChange将被触发。现在的方法是,它在声明组件时执行handleChange方法,而这不是您想要的。

wz1wpwve

wz1wpwve2#

正如我在您的代码中看到的,在您的Page组件中,下面的代码片段将usersData视为useQuery返回的结果,即QueryObserverRefetchErrorResult

const users = trpc.users.getUsersSummary.useQuery(
{},
{
    onError(err) {
        console.log('Failed to retrieve users summary')
    },
});
const [usersData, setUsersData] = useState(users);`

现在当你点击按钮updateFilter被调用(nahuelhds也提到语法错误请检查),其中调用filteredLists返回一个数组,所以你基本上是试图分配一个数组到QueryObserverRefetchErrorResult.
为了解决这个问题,而不是将QueryObserverRefetchErrorResult分配给usersData,您应该首先创建一个数组,然后将数组存储在状态中。你应该只将filterQueryStr保存为一个状态,而不是将过滤后的数组存储在状态中。考虑下面的代码。

const Page = () => {    
const users = trpc.users.getUsersSummary.useQuery(
    {},
    {
        onError(err) {
            console.log('Failed to retrieve users summary')
        },
    },
);
const [usersData, setUsersData] = useState([]);
const [filterQuery,setFilterQuery]=useState('')

//when query response change
useEffect(()=>{
    //you can use shorthand syntax like users?.data?.users
    if(users && users.data && Array.isArray(users.data.users)){
        setUsersData(users.data.users)
    }
},[users])

const filteredLists = useMemo((username: string) => {       
    if(filterQuery==='')return  usersData
    return usersData.filter((user: any) =>{
        //you can also try user.name.includes(filterQuery) for short keywords
        return user.name === filterQuery;
    });
},[filterQuery,usersData])

//updateFilter will only update filterQuery string, you can directly pass setFilterQuery to child component
const updateFilter = useCallBack((username: string) => {
    setFilterQuery(username)
});

return (
    <div>
        <UserList setUserType={updateFilter} usersSummary={filteredLists}     />
    </div>
)
  }

我希望这会有所帮助。

相关问题