以下是我的代码
const [accountUsers, setAccountUsers] = useState([]);
const [listLoading, setListLoading] = useState(true);
const [totalAccountUsers, setTotalAccountUsers] = useState(0);
const getAccountUserList = useCallback(
async (page = 0, pageSize = 10) => {
console.log('Kitne users hain??==', accountUsers.length);
if (
// TODO: Move this logic to action for reusability
accountUsers.length < (page + 1) * pageSize &&
(accountUsers.length < totalAccountUsers || accountUsers.length === 0)
) {
console.log('inside if condition');
console.log(' Total Account users=', totalAccountUsers);
console.log(
'first condiont=',
' accountUsers.length < (page + 1) * pageSize ',
accountUsers.length < (page + 1) * pageSize,
' AND'
);
console.log(
'second one condition',
' accountUsers.length < totalAccountUsers =',
accountUsers.length < totalAccountUsers,
' OR ',
'second two condition',
' accountUsers.length === 0',
accountUsers.length === 0
);
setListLoading(true);
const data = await getAccountUsers(id, page + 1, pageSize);
setAccountUsers((users) => users.concat(data.data.data.results));
setTotalAccountUsers(data.data.data.total);
setListLoading(false);
}
},
[accountUsers, totalAccountUsers, id]
);
const refetchUsers = useCallback(() => {
setAccountUsers([]);
setTotalAccountUsers(0);
}, []);
useEffect(() => {
getAccountUserList();
}, [getAccountUserList]);
return (
<>
<Button onClick={() => refetchUsers()}>Refetch</Button>
<Button onClick={async ()=> await delete(id); refetchUsers()> Delete </Button>
</>
)
我的refetch函数单独调用时效果很好。但是,当涉及到异步函数时,回调将被调用两次。我感觉在refetch函数中,有两个setStates使它在效果的帮助下两次调用了回调。
为什么会发生这种情况?解决方法是什么? 如果在任何异步操作之前调用refref,它就可以正常工作。在触发效果之前对状态更新进行批处理是否有问题。
答案 0 :(得分:1)
通过压缩依赖关系树(并忽略一些无关的内容),您的代码可以有效地实现以下效果:
const Home = () => {
const [accountUsers, setAccountUsers] = useState<number[]>([]);
const [totalAccountUsers, setTotalAccountUsers] = useState(0);
React.useEffect(() => {
const getAccountUserList = async () => {
const data = await Promise.resolve({results: [1, 2, 3]});
setAccountUsers((users) => users.concat(data.results));
setTotalAccountUsers(data.results.length);
};
getAccountUserList();
},
[accountUsers, totalAccountUsers]);
const refetchUsers = () => {
setAccountUsers([]);
setTotalAccountUsers(0);
};
return (
<>
<button onClick={() => refetchUsers()}>Refetch</button>
</>
);
};
我们可以在这里轻松发现问题-由useEffect挂钩引起的无限重渲染。您看到api被调用的可能性是两次,因为(幸运的是)它已经完成了所有数据的读取,并且代码中的if条件停止了进一步的状态更新。
一些个人建议:
以下代码(再次简化)适用于您的情况:
const Home = () => {
const [accountUsers, setAccountUsers] = useState<number[]>([]);
const [totalAccountUsers, setTotalAccountUsers] = useState(0);
const getAccountUserList = async () => {
const data = await Promise.resolve({results: [1, 2, 3]});
setAccountUsers((users) => users.concat(data.results));
setTotalAccountUsers(data.results.length);
};
React.useEffect(() => {
getAccountUserList();
}, []);
const refetchUsers = () => {
setAccountUsers([]);
setTotalAccountUsers(0);
getAccountUserList();
};
return (
<>
<button onClick={() => refetchUsers()}>Refetch</button>
</>
);
};