Я пытаюсь создать пользовательскую систему, но я что-то путаю, потому что она не работает в реальном времени.
Я создал пример Песочница , чтобы показать мою проблему"и мой код.Я не добавил никаких проверок, это только для примера.
Вот некоторые из проблем (я вижу):
- Действия кнопки запускаются при втором нажатии
- Данные не будут обновляться после создания / удаления.
Это компонент <UsersPage />
:
import React, { Fragment, useState, useEffect } from "react";
import { useMutation, useLazyQuery } from "@apollo/react-hooks";
import { ADD_USER, LIST_USERS, DELETE_USER } from "../../../config/constants";
import { useSnackbar } from "notistack";
import {
Grid,
Paper,
TextField,
Button,
Typography,
MenuItem,
FormHelperText
} from "@material-ui/core";
import AddUserIcon from "@material-ui/icons/PersonAdd";
import { withStyles } from "@material-ui/core/styles";
import PropTypes from "prop-types";
import Table from "../../Table";
const styles = theme => ({
grid: {
margin: theme.spacing(3)
},
icon: {
marginRight: theme.spacing(2)
},
form: {
width: "100%",
marginTop: theme.spacing(3),
overflowX: "auto",
padding: theme.spacing(2)
},
submit: {
margin: theme.spacing(2)
},
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing.unit,
marginRight: theme.spacing.unit
},
root: {
width: "100%",
marginTop: theme.spacing(3),
overflowX: "auto",
padding: theme.spacing(2)
},
title: {
margin: theme.spacing(2)
},
table: {
minWidth: 700
},
noRecords: {
textAlign: "center"
},
button: {
margin: theme.spacing.unit
}
});
const Users = props => {
const [idState, setIdState] = useState(null);
const [emailState, setEmailState] = useState("");
const [passwordState, setPasswordState] = useState("");
const [usersState, setUsersState] = useState([]);
const [errorsState, setErrorsState] = useState({});
const [loadingState, setLoadingState] = useState(false);
const [addUser, addUserResponse] = useMutation(ADD_USER);
const [loadUsers, usersResponse] = useLazyQuery(LIST_USERS);
const [deleteUser, deleteUserResponse] = useMutation(DELETE_USER);
const { enqueueSnackbar } = useSnackbar();
useEffect(() => {
loadUsers();
if (usersResponse.called && usersResponse.loading) {
setLoadingState(true);
} else if (usersResponse.called && !usersResponse.loading) {
setLoadingState(false);
}
if (usersResponse.data) {
setUsersState(usersResponse.data.getUsers);
}
}, [usersResponse.called, usersResponse.loading, usersResponse.data]);
function handleSubmit(e) {
e.preventDefault();
if (idState) {
} else {
addUser({
variables: {
email: emailState,
password: passwordState
}
});
}
if (addUserResponse.called && addUserResponse.loading) {
enqueueSnackbar("Creating user");
}
if (addUserResponse.error) {
addUserResponse.error.graphQLErrors.map(exception => {
const error = exception.extensions.exception;
const messages = Object.values(error);
enqueueSnackbar(messages[0], { variant: "error" });
});
}
if (addUserResponse.data && addUserResponse.data.addUser) {
enqueueSnackbar("user created", { variant: "success" });
loadUsers();
}
}
function handleEdit(user) {
setIdState(user.id);
setEmailState(user.email);
}
async function handleDelete(data) {
if (typeof data === "object") {
data.map(id => {
deleteUser({ variables: { id } });
if (deleteUserResponse.data && deleteUserResponse.data.deleteUser) {
enqueueSnackbar("User deleted", { variant: "success" });
}
});
} else {
deleteUser({ variables: { id: data } });
if (deleteUserResponse.data && deleteUserResponse.data.deleteUser) {
enqueueSnackbar("User deleted", { variant: "success" });
}
}
}
function resetForm() {
setIdState(null);
setEmailState("");
}
const { classes } = props;
return (
<Fragment>
<Grid container spacing={8}>
<Grid item xs={3} className={classes.grid}>
<Paper className={classes.form}>
<Typography variant="h6" className={classes.title}>
{idState ? `Edit user: ${emailState}` : "Create user"}
</Typography>
<form className={classes.container} onSubmit={handleSubmit}>
<input type="hidden" name="id" value={idState} />
<TextField
className={classes.textField}
label="E-mail address"
type="email"
variant="outlined"
margin="normal"
autoComplete="email"
id="email"
name="email"
required={!idState}
fullWidth
onChange={e => setEmailState(e.target.value)}
value={emailState}
aria-describedby="email-error"
/>
<FormHelperText id="email-error">
{errorsState.email}
</FormHelperText>
<TextField
className={classes.textField}
label="Password"
variant="outlined"
margin="normal"
autoComplete="password"
id="password"
name="password"
required={!idState}
type="password"
fullWidth
onChange={e => setPasswordState(e.target.value)}
value={passwordState}
aria-describedby="password-error"
/>
<FormHelperText id="password-error">
{errorsState.password}
</FormHelperText>
<Button
variant="contained"
color="primary"
className={classes.submit}
size="large"
type="submit"
>
<AddUserIcon className={classes.icon} /> Save
</Button>
<Button
variant="contained"
color="secondary"
className={classes.submit}
type="button"
onClick={resetForm}
>
<AddUserIcon className={classes.icon} /> Add new
</Button>
</form>
</Paper>
</Grid>
<Grid item xs={8} className={classes.grid}>
<Paper className={classes.root}>
<Table
data={usersState}
className={classes.table}
columns={{
id: "ID",
email: "E-mail address"
}}
classes={classes}
title="Users"
handleEdit={handleEdit}
handleDelete={handleDelete}
filter={true}
loading={loadingState}
/>
</Paper>
</Grid>
</Grid>
</Fragment>
);
};
Users.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(Users);
В случае, если вам нужно больше кода или редактирования:
Песочница веб-интерфейса: Приложение / Код
Любые комментарии, предложения или что-то будет оценено.