使用状态与使用局部变量进行反应,状态有效,但局部变量无效



我试图创建一个函数来检索数据库中的所有用户,但是,如果我试图像图像中那样只使用局部变量,它根本不起作用。如果我尝试使用State(注释的代码(,当我认为它们之间应该没有区别时,它就会起作用。用户列表用于TableBody部分中的映射函数。

const RegisteredUsers = () => {
//const [customers, setCustomers] = useState([]);
let customers = [];
useEffect(async () => {
await userService.getAll().then(customersList =>{
//setCustomers(customersList);
customers = customersList;
}).catch((err)=> {
console.log("Error: ", err);
});
});
return (
<Box
sx={{
backgroundColor: "background.default",
p: 3,
}}
>
<Card>
<Divider/>
<Box
sx={{
alignItems: "center",
display: "flex",
flexWrap: "wrap",
m: -1,
p: 2,
}}
>
<Box
sx={{
m: 1,
maxWidth: "100%",
width: 500,
}}
>
<TextField
fullWidth
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon fontSize="small"/>
</InputAdornment>
),
}}
placeholder="Search customers"
variant="outlined"
/>
</Box>
<Box
sx={{
m: 1,
width: 240,
}}
>
<TextField
label="Sort By"
name="sort"
select
SelectProps={{native: true}}
variant="outlined"
>
{sortOptions.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</TextField>
</Box>
</Box>
<Scrollbar>
<Box sx={{minWidth: 700}}>
<Table>
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox color="primary"/>
</TableCell>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Role</TableCell>
<TableCell>Company Id</TableCell>
<TableCell align="right">Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{customers.map((customer) => (
<TableRow hover key={customer.id}>
<TableCell padding="checkbox">
<Checkbox color="primary"/>
</TableCell>
<TableCell>
<Box
sx={{
alignItems: "center",
display: "flex",
}}
>
<Avatar
alt={customer.client_name}
sx={{
height: 42,
width: 42,
}}
/>
<Box sx={{ml: 1}}>
<Link color="inherit" variant="subtitle2">
{customer.client_name}
</Link>
</Box>
</Box>
</TableCell>
<TableCell>
<Typography color="textSecondary" variant="body2">
{customer.email}
</Typography>
</TableCell>
<TableCell>{customer.role}</TableCell>
<TableCell>{customer.company_id}</TableCell>
<TableCell align="right">
<IconButton>
<PencilAltIcon fontSize="small"/>
</IconButton>
<IconButton>
<ArrowRightIcon fontSize="small"/>
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Scrollbar>
<TablePagination
component="div"
count={customers.length}
onPageChange={() => {
}}
onRowsPerPageChange={() => {
}}
page={0}
rowsPerPage={5}
rowsPerPageOptions={[5, 10, 25]}
/>
<Comments/>
</Card>
</Box>
)
};

这是我的userService.getAll((

export const userService = {
getAll,
getById
};
async function getAll() {
let customers = [];
await axios.get("http://localhost:3000/api/v1/users", {
headers: authHeader()
}).then(customersList => {
customers.push(...customersList.data.users);
}).catch((err)=> {
console.log("Error: ", err);
})
return customers;
}

我尝试了很多方法,包括使用异步函数,因为我认为React可能会在分配给客户的值之前进行渲染,但效果不佳。

我是React的新手,所以任何帮助都会很棒!谢谢

这正是您需要状态的原因。

在第一次尝试中,组件在为customers指定新值之前已经渲染,不会重新渲染。

我认为React可能在价值分配给客户之前进行渲染

正如您所猜测的,您有两种方法可以指示组件重新渲染:

  • 更改组件状态(如钩子中(
  • 更改组件道具

需要这两个选项中的一个来指示react重新计算组件

关键提示是,useState将通过重新发布程序保留其值,而更改状态将触发重新发布程序。这意味着,如果在渲染后将某个内容存储在普通变量中,它将不会显示在DOM中,因为仍然有来自上一次渲染的值。如果您触发了新的渲染,那么您的变量将用空数组重新声明,并且您处于获取之前的位置。

在运行时,本地变量值将被同步调用(不知道何时会用数据填充(,请在映射中添加以下检查,以确保它在值存在时运行:

sortOptions&amp;sortOptions?。地图(…(

此外,当您从API获取值时,react建议使用带有useState的state。

最新更新