React Hooks form OnSubmit makes Problems - reactjs

Hey i cant find a solution why my code dosent work. When i trigger the button nothing happens, normally i want to display the data but nothing happend. My Code is in attachment.
if someone has an idde to solve the problem I would be very grateful.
I have looked at other posts but nothing helps with my Problem.
export default function FormDialog(props) {
const [open, setOpen] = React.useState(false);
const {
control,
formState: { errors },
setValue,
} = useFormContext();
let isError = false;
let errorMessage = "";
if (errors && errors.hasOwnProperty(name)) {
isError = true;
errorMessage = errors[name].message;
}
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
props.func();
};
const handleChange = (event) => {
props.setMenge(event.target.value);
};
React.useEffect(() => {
if (errors) {
console.log(errors);
}
}, [errors]);
return (
<>
<Button variant="contained" onClick={handleClickOpen}>
Umbuchen
</Button>
<Dialog open={open} onClose={handleClose}>
<DialogTitle>Umbuchung</DialogTitle>
<DialogContent>
<DialogContentText>
Bitte geben Sie die Menge ein die umgelagert werden soll!
</DialogContentText>
<Controller
control={control}
name={props.name}
render={({ field }) => (
<TextField
{...field}
label={props.label}
error={isError}
helperText={errorMessage}
autoFocus
margin="dense"
id="menge"
type="number"
fullWidth
variant="standard"
/>
)}
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Schließen</Button>
<Button variant="contained" color="primary" type="submit">
Umbuchen
</Button>
</DialogActions>
</Dialog>
</>
);
}
export default function Home() {
const [sEingang, setSEingang] = useState([]);
const [sLager, setSLager] = useState("");
const [menge, setMenge] = useState(0);
const context = React.useContext(AuthContext);
const { data: warendata } = useWaren(context.access_token);
const { data: lagerdata } = useGetLager(context.access_token);
const methods = useForm({
resolver: yupResolver(validationShema),
mode: "all",
});
const { getValues, reset, watch, handleSubmit } = methods;
const waren = watch("selWaren");
const { data: chargendata, refetch } = useChargen({
access_token: context.access_token,
lager: waren,
});
const { mutateAsync, isError: mutError, isLoading, isSuccess } = useAnlegen();
React.useEffect(() => {
async function getToken() {
const res = await context.setTokenSilently();
}
const interval = setInterval(() => {
getToken();
}, 30000);
return () => clearInterval(interval);
}, []);
const onSubmit = (data) => {
console.log("data: ", data);
};
return (
<>
<CssBaseline />
<ButtonAppBar name={"Wareneingänge"} back={false} onClick={reset} />
<FormProvider {...methods}>
<form onSubmit={handleSubmit(onSubmit)}>
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justifyContent="center"
sx={{p: 2, m: 3}}
style={{ minHeight: "50vh", }}
>
<Grid item xs={3}>
<MySelect
formname={"selWaren"}
data={warendata}
name={"Wareneingänge"}
selected={sEingang}
setSelected={setSEingang}
reset={reset} />
</Grid>
<Grid item xs={3}>
<MySelect
formname={"selLager"}
data={lagerdata}
name={"Freie Lagerplätze"}
selected={sLager}
setSelected={setSLager} />
</Grid>
<Grid item xs={3}>
<MySelect
formname={"selChargen"}
data={chargendata}
name={"Freie Chargenplätze"}
selected={sLager}
setSelected={setSLager} />
</Grid>
<Grid item xs={3} sx={{ m: 3}}>
<FormDialog
func={onSubmit}
name={"selMenge"} />
</Grid>
</Grid>
</form>
</FormProvider>
</>
);
}

It looks like you've forgotten to add an onClick handler for the submit button here:
<Button variant="contained" color="primary" type="submit">
Umbuchen
</Button>
Something like this should work:
<Button onClick={() => props.func()} variant="contained" color="primary" type="submit">
Umbuchen
</Button>

Related

How to update existing data from DB with react-hook-form

I'm creating an E-commerce like website, we upload products through the admin site.
I have Upload.tsx file like so:
...
import FormDetails from '#components/FormDetails';
const Upload: React.FC = () => {
const { register, handleSubmit, reset, unregister, watch, setValue } =
useForm<UploadFormState>();
const watchPacksOrWholesale = watch('packsOrWholesale');
const [uploadLoading, setUploadLoading] = useState<boolean>(false);
const [file, setFile] = useState<File | null>(null);
const [url, setUrl] = useState<string>('');
const [progress, setProgress] = useState<number>(0);
const [createdAt, setCreatedAt] = useState<Timestamp | null>(null);
const saveProduct = useProductStore((state) => state.saveProduct);
const isLoading = useProductStore((state) => state.isLoadingSave);
const handleProductSubmit: SubmitHandler<UploadFormState> = (data) => {
const newProductUpload = {
drinkName: data.drinkName,
description: data.description,
category: data.category,
price: Number(data.price),
url,
createdAt,
packsOrWholesale: data.packsOrWholesale,
packSize: data.packSize,
};
saveProduct(newProductUpload, reset, setFile);
};
return (
<>
<Text fontSize="xl" mb={5} fontWeight="semibold">
Upload Drinks
</Text>
<form onSubmit={handleSubmit(handleProductSubmit)}>
<FormDetails
register={register}
file={file}
progress={progress}
setFile={setFile}
setProgress={setProgress}
isRequired={true}
unregister={unregister}
watchPacksOrWholesale={watchPacksOrWholesale}
setValue={setValue}
/>
<ButtonGroup mt={4} spacing={2}>
<Button
size="sm"
isLoading={uploadLoading}
isDisabled={!file || progress === 100}
onClick={handleProductImageUpload}
>
Upload Image
</Button>
<Button
size="sm"
type="submit"
variant="solid"
// isDisabled={!file || progress === 0}
colorScheme="success"
isLoading={isLoading}
>
Save Product
</Button>
</ButtonGroup>
</form>
</>
);
};
export default Upload;
.....
FormDetails.tsx
import {
....
} from '#chakra-ui/react';
import { FileInput } from '#components/FormFields';
import { drinkCategoriesArray } from '#data/index';
import { FormDetailsProps } from '#interfaces/index';
import { useEffect, useState } from 'react';
import { Controller } from 'react-hook-form';
const FormDetails: React.FC<FormDetailsProps> = ({
....
}) => {
const [isPacksOrWholesale, setIsPacksOrWholesale] = useState<boolean>(
product?.packsOrWholesale || false
);
useEffect(() => {
if (watchPacksOrWholesale) {
register('packsOrWholesale', { required: true });
} else {
unregister('packsOrWholesale');
}
}, [register, unregister, watchPacksOrWholesale, isPacksOrWholesale]);
return (
<>
<SimpleGrid columns={{ base: 1, sm: 2 }} spacing={6} textAlign="left">
<FormControl>
<FormLabel fontSize="14px">Drink name</FormLabel>
<Input
{...register('drinkName', { required: isRequired })}
type={'text'}
placeholder="Meridian"
defaultValue={(showValue && product?.drinkName) || ''}
/>
</FormControl>
<FormControl>
<FormLabel fontSize="14px">Description</FormLabel>
<Input
{...register('description', { required: isRequired })}
type={'text'}
placeholder="Meridian wine is the best"
defaultValue={(showValue && product?.description) || ''}
/>
</FormControl>
<FormControl>
<FormLabel fontSize="14px">Select Category</FormLabel>
<Select
{...register('category', { required: isRequired })}
placeholder="Select category"
defaultValue={(showValue && product?.category) || ''}
>
{drinkCategoriesArray.map(({ drinkCategory, drink_id }) => (
<option key={drink_id} value={drinkCategory}>
{drinkCategory}
</option>
))}
</Select>
</FormControl>
<FormControl>
<FormLabel>
<FormLabel fontSize="14px">Select Product method</FormLabel>
<HStack>
<Text fontWeight={'semibold'}>Product in wholesale</Text>
<Switch
id="packs switch"
{...register('packsOrWholesale')}
colorScheme={'primary'}
size={'sm'}
fontWeight={'semibold'}
defaultChecked={showValue && product?.packsOrWholesale}
isChecked={isPacksOrWholesale}
onChange={() => setIsPacksOrWholesale(!isPacksOrWholesale)}
/>
<Text fontWeight={'semibold'}>Product in packs</Text>
</HStack>
</FormLabel>
</FormControl>
{isPacksOrWholesale ? (
<FormControl>
<FormLabel>
<FormLabel fontSize="14px">Select pack size</FormLabel>
<Select
{...register('packSize', {
required: true,
})}
placeholder="Select Pack Size"
defaultValue={(showValue && product?.packSize) || ''}
>
<option value="6 Packs">6 Packs</option>
<option value="12 Packs">12 Packs</option>
</Select>
</FormLabel>
</FormControl>
) : null}
<FormControl mt={'3px'}>
<FormLabel fontSize="14px">Price</FormLabel>
<Input
{...register('price', { required: isRequired })}
type="number"
placeholder="500 (in Dollars)"
defaultValue={(showValue && product?.price) || ''}
/>
</FormControl>
</SimpleGrid>
....
</Box>
</>
);
};
export default FormDetails;
.....
ProductEdit.tsx
import FormDetails from '#components/FormDetails';
import { useProductStore } from '#store/useProductStore';
const ProductEdit = forwardRef(({ product }: ProductType, ref) => {
const { id } = useParams<ProductParams>();
const { register, handleSubmit, watch, unregister, reset, setValue } =
useForm<UploadFormState>();
const watchPacksOrWholesale = watch('packsOrWholesale');
const [file, setFile] = useState<File | null>(null);
const [uploadLoading, setUploadLoading] = useState<boolean>(false);
const [url, setUrl] = useState<string>('');
const [progress, setProgress] = useState<number>(0);
const { isOpen, onOpen, onClose } = useDisclosure();
const editProduct = useProductStore((state) => state.editProduct);
const isLoading = useProductStore((state) => state.isLoadingEdit);
const handleProductUpdate: SubmitHandler<UploadFormState> = (data) => {
const newUpdate = {
drinkName: data.drinkName || product?.drinkName,
description: data.description || product?.description,
category: data.category || product?.category,
url: url || product?.url,
price: Number(data.price) || Number(product?.price),
packsOrWholesale: data.packsOrWholesale || product?.packsOrWholesale,
packSize: data.packSize || product?.packSize,
};
// editProduct(id, newUpdate, onClose, setFile);
console.log(newUpdate);
};
return (
<Box>
<IconButton
aria-label="edit-button"
size="sm"
colorScheme="secondary"
variant="ghost"
onClick={onOpen}
icon={<RiPencilLine size="18px" />}
/>
<Modal
isCentered
size="lg"
onClose={onClose}
isOpen={isOpen}
motionPreset="slideInBottom"
closeOnOverlayClick={false}
>
<ModalOverlay backdropFilter={'blur(5px)'} />
<ModalContent>
<ModalHeader>
Edit Product{' '}
<chakra.span color="success.700">{product?.drinkName}</chakra.span>?
</ModalHeader>
<ModalCloseButton size="sm" />
<form onSubmit={handleSubmit(handleProductUpdate)}>
<ModalBody>
<FormDetails
register={register}
file={file}
progress={progress}
setFile={setFile}
setProgress={setProgress}
showValue={true}
isRequired={false}
product={product}
unregister={unregister}
watchPacksOrWholesale={watchPacksOrWholesale}
setValue={setValue}
/>
</ModalBody>
<ModalFooter>
<ButtonGroup mt={4} spacing={2}>
<Button
isLoading={uploadLoading}
onClick={handleProductImageUpload}
isDisabled={!file || progress === 100}
size="sm"
>
Upload Image
</Button>
<Button
size="sm"
type="submit"
variant="solid"
isLoading={isLoading}
colorScheme="success"
>
Update Product
</Button>
</ButtonGroup>
</ModalFooter>
</form>
</ModalContent>
</Modal>
</Box>
);
});
export default ProductEdit;
I have a reusable component, called FormDetails. I use this component to get the data from the admin input and do an upload. Alternatively, I also use it for the ProductEdit component.
Everything works fine, except for the fact that,
in the FormDetails component, I want to use react-hook-form to manage the state of what renders. i.e if watchPacksOrWholesale is true, which is linked to the Switch component, the Select component which holds the packSize should show.
The ProductEdit component picks the existing Product from firebase and then on editing the product using react-hook-form if I disable the Switch component the value for the PackSize should be an empty string, meaning I don't want a packSize. I should be able to update the product on Firebase.
All I'm saying is that the Switch component does not update well.

React Slide Animation removing selected value on unmountOnExit

I am facing a issue, on click of radio button the next question comes using slide animation, But on unmounting on Exit the previously selected radio button value is also getting deselected. How to prevent this from happening.
const Quiz = (props) => {
const {questions, quiz, options} = useSelector((state) => state.quiz);
const [user, setuser] = useState("");
const [currentQuestion, setCurrentQuestion] = useState(0);
const [checked, setChecked] = useState(true);
const [option, setOptions] = useState("");
const dispatch = useDispatch();
const history = useHistory();
const handleRadioChange = (number, event) => {
let currentSelection = questions.find(question => question.number === number);
console.log(currentSelection + "radio selected");
currentSelection.value = event.target.value;
questions[currentQuestion].value = event.target.value;
console.log(questions[currentQuestion].value + "value added");
setCurrentQuestion((current) => {
return Math.min(
current + 1,
questions.length - 1
);
});
setChecked((previousState) => !previousState);
setTimeout(() => {
setChecked(previousState => ({
afterPreviousChange: previousState.previousChange
}))
}, 1000);
};
const previousQuestion = (event) => {
event.preventDefault();
let new_current_questions = Math.max(currentQuestion - 1, 0);
setCurrentQuestion(new_current_questions);
setChecked((previousState) => !!previousState);
const a = setTimeout(() => {
setChecked(previousState => ({
afterPreviousChange: previousState.previousChange
}))
}, 1000);
};
function handleSubmit(event) {
event.preventDefault();
const valid = questions.some((q) => !q.value);
console.log(valid + "questionsalpha");
if (!valid) {
dispatch(postQuiz({ responses: questions, id: quiz.id }, history));
}
setChecked((previousState) => !previousState);
const a = setTimeout(() => {
setChecked((previousState) => !previousState);
setCurrentQuestion(0);
},1000);};
return(
<Slide direction="up"
in={checked}
appear={true}
mountOnEnter
unmountOnExit
timeout={{ enter: 1000 , exit: checked ? 1 : 900}}
>
<Card variant="outlined" sx={{ bgcolor: "#bea"}} elevation={0}>
<CardContent>
<form onSubmit= {handleSubmit}>
<CardActions>
<Button type="submit" color="warning" variant="outlined" disabled={currentQuestion===0} className={classes.button} onClick={previousQuestion}>
Previous</Button>
</CardActions>
<FormControl component='fieldset' className={classes.formControl}
data-hidden={questions[currentQuestion].number !==
currentQuestion[questions[currentQuestion].number]} >
<FormLabel component='legend'>
{questions[currentQuestion].question}
</FormLabel>
<FormLabel component='legend'>
{questions[currentQuestion].description}
</FormLabel>
<RadioGroup
aria-label='quiz'
name='quiz'
defaultValue={' '}
value={questions[currentQuestion].value}
checked={checked}
onChange={(e)=> handleRadioChange(questions[currentQuestion].number, e)}
sx={{
color: pink[800],
'&.Mui-checked': {
color: blue[600],
},
}}>
{options.map((option) => (
<FormControlLabel
key={option.score}
value={option.score}
control={<Radio sx={{
color: pink[800],
'&.Mui-checked': {
color: blue[600],
},
}}/>}
label={option.label}
/>
))}
</RadioGroup>
</FormControl>
<CardActions>
<Button type="submit" variant="contained" color="primary" className={classes.button} disabled={currentQuestion<5} onClick={handleSubmit}>
Submit
</Button>
</CardActions>
</form>
</CardContent>
</Card>
</Slide>
);
function using handleChange and previous button is also I have shared. Please help with this issue.
The main reason for previously radio button value not persist is because you are not changing the questions state with the update values, you are just changing the object itself.
The error is specifically here:
let currentSelection = questions.find(question => question.number === number);
console.log(currentSelection + "radio selected");
// HERE YOU ARE CHANGIG ONLY THE OBJECT, NOT THE ARRAY
currentSelection.value = event.target.value;
questions[currentQuestion].value = event.target.value;
One way to do this is map the questions array, change the current question value and then update the questions state:
const updatedQuestions = questions.map((item) => {
if (item.number === currentQuestion) item.value = event.target.value;
return item;
});
setQuestions(updatedQuestions);
But your code also have other inconsistencies, i did a code sample for you with comments.

firebase Error : FirebaseError: Missing or insufficient permissions

so I'm getting these Errors out of nowhere, I worked with the code yesterday and everything was fine.
This is like a social Media platform and
yesterday I could display the Posts, and today I can't. I can still take pictures and save it in the Firebase DB that works fine but it won't post itself at the feed.
This is the Code:
function Profile(props) {
const classes = useStyles();
const [reason, setReason] = React.useState('');
const [open, setOpen] = React.useState(false);
const handleChange = (event) => {
setReason(event.target.value);
};
const handleClose = () => {
setOpen(false);
};
const handleOpen = () => {
setOpen(true);
};
const [userPosts, setUserPosts] = useState([]);
const [user, setUser] = useState(null);
const [following, setFollowing] = useState(false)
useEffect(() => {
const { currentUser, posts } = props;
console.log({ currentUser, posts });
if (props.route.params.uid === firebase.auth().currentUser.uid) {
setUser(firebase.auth().currentUser);
setUserPosts(posts);
}else{
firebase.firestore()
.collection("users")
.doc(props.route.params.uid)
.get()
.then((snapshot) =>{
if(snapshot.exists){
setUser(snapshot.data())
}else{
console.log('does not exist')
}
})
firebase.firestore()
.collection("posts")
.doc(props.route.params.uid)
.collection("userPosts")
.orderBy("creation", "asc")
.get()
.then((snapshot) =>{
let posts = snapshot.docs.map(doc => {
const data = doc.data();
const id = doc.id;
return{id, ...data}
})
setUserPosts(posts)
})
}
if(props.following.indexOf(props.route.params.uid) > -1){
setFollowing(true);
}else{
setFollowing(false)
}
},[props.route.params.uid, props.following]);
const onFollow = () =>{
firebase.firestore()
.collection("following")
.doc(firebase.auth().currentUser.uid)
.set({
following : [props.route.params.uid]
})
}
const onLogout = () =>{
firebase.auth().signOut();
}
if (user === null) {
return <View />;
}
return (
<div className={classes.div}>
<div >
<Avatar alt="Ana Pädagogin" className={classes.avatar} />
<Typography className={classes.text} > {user.name} </Typography>
<Typography className={classes.text} > {user.email} </Typography>
{props.route.params.uid !== firebase.auth().currentUser.uid ? (
<Container>
{following ? (
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onUnFollow()}
>Following</Button>
) :
(
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onFollow()}
>Follow</Button>
)}
</Container>
) : <Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onLogout()}
>Logout</Button>}
<Card>
{/* //Verspätung */}
<CardContent>
<Typography variant="h5" className={classes.cardTyp}> Verspätung </Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
className={classes.cardTime}
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
/>
<Button className={classes.cardBtn}>Absenden</Button>
</Container>
</CardContent>
{/* //Krankenmledungen */}
<CardContent className={classes.cardKrankmeldung}>
<Typography variant="h5" className={classes.cardTyp}> Krankenmledungen </Typography>
<Container className={classes.cardContainer}>
<TextField
id="date"
label="Von"
type="date"
defaultValue="2017-05-24"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
<TextField
id="date"
label="bis"
type="date"
defaultValue="2017-05-24"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
</Container>
<Button className={classes.cardBtn}>Absenden</Button>
</CardContent>
{/* //Verspätung Abolung*/}
<CardContent>
<Typography variant="h5" className={classes.cardTyp}> Verspätung Abholung</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
/>
<Button className={classes.cardBtn}>Absenden</Button>
</Container>
</CardContent>
</Card>
</div>
</div>
)
}
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser,
posts: store.userState.posts,
following: store.userState.following
});
export default connect(mapStateToProps, null)(Profile);
As Frank van Puffelen pointed out your problem lies in Firebase Firestore security rules.
If you can save post on db, it seems that you have write permission but not read permission on that collection.
You can test how changing security rules affect this problem by first enabling all reads and writes to that collection
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /yourCollectionName/{ID}{
allow read, write: if true;
}
}
}
, and then restricting the collection as you need.
Check these guides to apply needed modifications and best practices to your security rules.
https://firebase.google.com/docs/firestore/security/get-started
https://firebase.google.com/docs/firestore/security/rules-structure

React: change state after fetch in functional component

I have the following component:
export default function SignIn() {
const [isLoading, setIsLoading] = useState(false);
const classes = useStyles();
const handleSubmit = (event) => {
event.preventDefault();
if(!AuthService.login(event.target))
{
setIsLoading(false);
}
}
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate onSubmit={(event) => { handleSubmit(event); setIsLoading(true); }}>
{ isLoading ?
<CircularProgress/> :
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
}
</form>
</div>
</Container>
);
}
When I submit the form, the "isLoading" becomes true, and the loading bars show up. Anyway if the "AuthService.login()" fails, the "isLoading" state is not updated.
What am I doing wrong?
Working code
The problem was related to the fact that
if(!AuthService.login(event.target))
is an async function, so I had to "await" for the response in order to evaluate it's result.
The working code:
async function handleSubmit (event) {
event.preventDefault();
setIsLoading(true)
try {
await AuthService.login(event.target);
setIsLoading(false)
} catch (e) {
console.log('Handle errors here');
} finally {
console.log('We do cleanup here');
}
}
Change:
onSubmit={(event) => { handleSubmit(event); setIsLoading(true); }}
to:
onSubmit={(event) => { handleSubmit(event) }}
Also change handleSubmit to:
const handleSubmit = (event) => {
event.preventDefault();
setLoading(true);
if(!AuthService.login(event.target))
{
setIsLoading(false);
}
}
you are always setting isLoading to true in onSubmit
export default function SignIn() {
const [isLoading, setIsLoading] = useState(false);
const classes = useStyles();
const handleSubmit = (event) => {
event.preventDefault();
setLoading(true)
if(!AuthService.login(event.target))
{
setIsLoading(false);
}
}
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} noValidate onSubmit={(event) => { handleSubmit(event) }}>
{ isLoading ?
<CircularProgress/> :
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
}
</form>
</div>
</Container>
);
}

Can't send post request to authenticate user in react & redux

I have implemented all of actions and want to call that action with username and password parameters to authenticate user in form.But when I click submit no request is being sended and nothing happens.Code is a little bit long so I'm gonna cut the main part.
actions.js
const authStart = () => {
return {
type: "AUTH_START",
};
};
const authSucceed = (token) => {
return {
type: "AUTH_SUCCESS",
payload: token,
};
};
const authFailed = (error) => {
return {
type: "AUTH_FAILED",
payload: error,
};
};
export const authLogin = (username, password) => {
return (dispatch) => {
dispatch(authStart());
axios
.post("http://127.0.0.1:8000/rest-auth/login/", {
username: username,
password: password,
})
.then((res) => {
const token = res.data.key;
dispatch(authSucceed(token));
})
.catch((err) => {
dispatch(authFailed(err));
});
};
};
SignIn.js
const SignIn = (props) => {
const classes = useStyles();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
// const [username,setUsername] = useState("")
// const [password,setPassword] = useState("")
const submitHandler = (e) => {
e.preventDefault();
props.onAuth(username,password)
setUsername("");
setPassword("");
};
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form onSubmit={submitHandler} className={classes.form} noValidate>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="username"
label="Username"
name="username"
autoComplete="username"
autoFocus
onChange={(e) => setUsername(e.target.value)}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={(e) => setPassword(e.target.value)}
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link to="/signup" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</form>
</div>
<Box mt={8}>
<Copyright />
</Box>
</Container>
);
};
const mapStateToProps = state => {
return state.Auth
}
const mapDispatchToProps = dispatch => {
return {
onAuth: (username,password) => {authLogin(username,password)}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(SignIn);
I'll be grateful if you help me out with this.Thanks
Looking at the way your code is setup, authLogin returns a function which takes dispatch as a param, so you probably need to do:
onAuth: (username,password) => {authLogin(username,password)(dispatch)}
You could use bindActionCreators() as well to return the dispatch function, in the following way:-
const mapDispatchToProps = (dispatch) => {
return {
actions: bindActionCreators(authLogin(username,password), dispatch)
}
}
If you want another way to do the same, you could refer to the link below.
https://blog.logrocket.com/react-redux-connect-when-and-how-to-use-it-f2a1edab2013/

Resources