Changing class component to functional component in React - reactjs

I have this code and tried to convert it to functional component and I am stuck. I have a form in return() part that passes the value to the state and then to props? via mapStateToProps as far as I understand... But, switching to function() component, I am lost what I have to do here.
class Login extends Component {
state = {
login: '',
password: '',
keepLogged: false
};
changeValue = event => {
event.preventDefault();
const value = event.target.value;
const name = event.target.name;
this.setState({
[name]: value
});
};
loginUser = () => {
const { login, password } = this.state;
const { requestSignIn } = this.props;
requestSignIn({ login, password });
};
render() {
const { login, password } = this.state;
return (
<LoginWrapper>
<Container style={{ border: '1px solid #757575', padding: '5%' }}>
<Row>
<Col style={{ textAlign: 'right', marginRight: '25px' }}>
</Col>
</Row>
<Row>
<Col>
<LoginHeader>Log In to Your Account</LoginHeader>
</Col>
</Row>
<Row>
<Col>
<LoginForm>
<FormControl
name='login'
type='text'
placeholder='Username/Email'
value={login}
onChange={this.changeValue}
style={{ marginBottom: '10px' }}
/>
<FormControl
name='password'
type='password'
placeholder='Password'
value={password}
onChange={this.changeValue}
style={{ marginBottom: '10px' }}
/>
<Button
variant='info'
value='Log In'
onClick={() => this.loginUser()}
>
Log In
</Button>
</LoginForm>
</Col>
</Row>
<Row>
<Col>
<LoginBottom
onClick={() => history.push('/registration')}
style={{ marginTop: '30px' }}
>
Need an account?{' '}
<Link style={{ color: '#007bff' }}>Sign Up</Link>
</LoginBottom>
</Col>
</Row>
</Container>
</LoginWrapper>
)
const mapDispatchToProps = dispatch => ({
requestSignIn: data => dispatch(requestSignIn(data))
});
export default connect(null, mapDispatchToProps)(Login);
So far, I have done this. I am stuck here. Tried to introduce useState for each login, password, and keepLogged but failed :/
function Login(props) {
const [inputs, setInputs] = useState({
// you can login with email or username
login: '',
password: '',
keepLogged: false
});
const { login, password } = inputs;
function handleChange(e) {
e.preventDefault();
const { name, value } = e.target;
setInputs(inputs => ({ ...inputs, [name]: value }));
}
const loginUser = () => {
const setInputs = inputs;
const { requestSignIn } = props;
requestSignIn({ setInputs });
};
return (
<Grid container component='main' className={classes.root}>
<CssBaseline />
<Grid item xs={false} sm={4} md={7} className={classes.image} />
<Grid item xs={12} sm={8} md={5} component={Paper} elevation={6} square>
<div className={classes.paper}>
<div>
<img src={Logo} style={{ width: 300 }} />
</div>
<Typography component='h1' variant='h5'>
Sign in
</Typography>
<form className={classes.form} noValidate>
<TextField
variant='outlined'
margin='normal'
required
fullWidth
id='email'
label='Email Address'
value={login}
onChange={handleChange}
name='login'
autoComplete='email'
autoFocus
/>
<TextField
variant='outlined'
margin='normal'
required
fullWidth
name='password'
label='Password'
value={password}
onChange={handleChange}
type='password'
id='password'
autoComplete='current-password'
/>
<FormControlLabel
control={<Checkbox value='remember' color='primary' />}
label='Remember me'
/>
<Button
type='submit'
fullWidth
variant='contained'
color='primary'
value='Log In'
className={classes.submit}
onClick={() => loginUser()}
>
Sign In 🙂
</Button>
<Grid container>
<Grid item xs>
<Link href='#' variant='body2'>
Forgot password?
</Link>
</Grid>
<Grid item>
<Link
variant='body2'
onClick={() => history.push('/registration')}
>
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
<Box mt={5}>
<Copyright />
</Box>
</form>
</div>
</Grid>
</Grid>
)
const mapDispatchToProps = dispatch => ({
requestSignIn: data => dispatch(requestSignIn(data))
});
export default connect(null, mapDispatchToProps)(Login);

I think you were most of the way there, just a case of clearing up some redundant code.
const [inputs, setInputs] = useState({
login: '',
password: '',
keepLogged: false
});
const { login, password } = inputs;
function handleChange(e) {
e.preventDefault();
const { name, value } = e.target;
// Set the inputs object directly, no need to callback
setInputs({ ...inputs, [name]: value });
}
const loginUser = () => {
const { requestSignIn } = props;
// Login and password are already initialised
requestSignIn({login, password});
};
You may also want to pass the event object to the handler like so:
onChange={e => handleChange(e)}

Related

FIrebase. User being registered as anonymous

i have a simple React signup application with firebase authentication. I'm using email and password to register users. Everything is working fine but the user is registered as (anonymous). I have enabled email/password authentication in firebase and I'm using createUserWithEmailAndPassword() function.
import React from "react";
import Card from "#mui/material/Card";
import TextField from "#mui/material/TextField";
import Typography from "#mui/material/Typography";
import Grid from "#mui/material/Grid";
import Box from "#mui/material/Box";
import CardContent from "#mui/material/CardContent";
import Button from "#mui/material/Button";
import Alert from "#mui/material/Alert";
import { auth } from "./../firebase";
import { Link } from "react-router-dom";
import GoogleButton from "react-google-button";
import { GoogleAuthProvider, signInWithRedirect } from "firebase/auth";
export const Signup: React.FC = () => {
const emailRef = React.useRef<any>();
const passwordRef = React.useRef<any>();
const passwordConfirmRef = React.useRef<any>();
const [error, setError] = React.useState("");
const [loading, setLoading] = React.useState<boolean>(false);
const googleSignIn = () => {
const provider = new GoogleAuthProvider();
// signInWithPopup(auth, provider);
signInWithRedirect(auth, provider);
};
async function handleSubmit(e: any) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match");
}
try {
setError("");
setLoading(true);
await auth.createUserWithEmailAndPassword(
emailRef.current!.value,
passwordRef.current!.value
);
} catch {
setError("Failed to create an account");
}
setLoading(false);
}
const handleGoogleSignIn = async () => {
try {
await googleSignIn();
} catch (error) {
console.log(error);
}
};
return (
<>
<Card sx={{ width: "400px" }}>
<CardContent>
<Typography textAlign="center" variant="h4" m={2}>
Sign Up
</Typography>
{error && (
<Alert severity="error" sx={{ marginBottom: 2 }}>
Passwords do not match
</Alert>
)}
<form onSubmit={handleSubmit}>
<Grid
container
direction="column"
justifyContent="center"
alignItems="stretch"
gap={2}
>
<Grid xs={12} sm={6} item>
<TextField
label="Email"
type="email"
autoComplete="email"
placeholder="Enter your email"
variant="outlined"
fullWidth
required
ref={emailRef}
/>
</Grid>
<Grid xs={12} sm={6} item>
<TextField
label="New Password"
type="password"
autoComplete="new-password"
placeholder="New Password"
variant="outlined"
fullWidth
required
ref={passwordRef}
/>
</Grid>
<Grid xs={12} sm={6} item>
<TextField
label="Confirm Password"
type="password"
autoComplete="new-password"
placeholder="Confirm New Password"
variant="outlined"
fullWidth
required
ref={passwordConfirmRef}
/>
</Grid>
</Grid>
<Button
type="submit"
variant="contained"
sx={{ marginTop: 2 }}
fullWidth
disabled={loading}
>
Sign Up
</Button>
</form>
</CardContent>
</Card>
<Box component="div" marginTop={2} textAlign="center">
<GoogleButton
style={{ width: "100%", marginBottom: 15 }}
onClick={handleGoogleSignIn}
/>
<Typography
variant="body1"
component="a"
href="#"
sx={{ textDecoration: "none" }}
>
<Link to="/login" style={{ textDecoration: "none" }}>
Already have an account? Log in
</Link>
</Typography>
</Box>
</>
);
};
According to the docs you should be passing the auth as the first prop in createUserWithEmailAndPassword(auth, email, password): https://firebase.google.com/docs/auth/web/password-auth#create_a_password-based_account:~:text=createUserWithEmailAndPassword(auth%2C%20email%2C%20password)
Also, make sure your email and password contain values and are not undefined.
try {
setError("");
setLoading(true);
const auth = getAuth();
await auth.createUserWithEmailAndPassword(
auth,
emailRef.current!.value,
passwordRef.current!.value
);
} catch {
setError("Failed to create an account");
}

React Hook Form is not submitting

I'm new with react form, I'm using Material UI and Controller Component, and I'm sending a React Hook form request but not getting any response, form's (HTML form tag) onSubmit event is occurring but handleSubmit is not working I have one more form like that it is working perfectly fine but I don't know why it's not working, can anybody please help me with that
import { Button, useTheme, Grid, TextField, Typography } from '#mui/material';
import WSSelectBox from 'components/common/WSSelect';
import React, { FC } from 'react';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { isMobile } from 'utils/mediaqueries';
import CheckBoxButton from '../CheckBoxButton';
import { formTypes } from './utils';
import { yupResolver } from '#hookform/resolvers/yup';
import * as yup from 'yup';
import { FormPropTypes } from './type';
const schema = yup
.object()
.shape({
name: yup.string().required(),
residentialCountry: yup.number().required(),
initiator: yup.string().required(),
program: yup.string().required(),
list: yup.string().required(),
})
.required();
const Entities: FC<FormPropTypes> = ({
handleClick,
selectedType,
handleSearch,
}) => {
const theme = useTheme();
const methods = useForm({
resolver: yupResolver(schema),
});
const { handleSubmit, control } = methods;
const onSubmit = (data) => {
// Backend is not done yet
console.log('DataData', data);
};
return (
<FormProvider {...methods}>
<form
onSubmit={(e) => {
e.preventDefault();
console.log('skdjskd', 'Line no 44');
handleSubmit(onSubmit);
}}
>
<Grid container spacing={'16px'}>
{formTypes.map((type) => (
<Grid item xs={6} sm={'auto'} md={'auto'} key={type}>
<CheckBoxButton
key={type}
name={'type'}
value={type}
handleClick={handleClick}
active={type == selectedType ? true : false}
/>
</Grid>
))}
</Grid>
<Grid container pt={4} columnSpacing="20px" rowSpacing={'16px'}>
<Grid item xs={12} sm={12} md={6}>
<Controller
name="name"
render={({
// eslint-disable-next-line #typescript-eslint/no-unused-vars
field: { value, ...otherFieldProps },
fieldState,
}) => (
<TextField
fullWidth
id="sanctions-form-name"
label="Name"
variant="outlined"
helperText={
<p
style={{
position: 'relative',
left: -13,
fontSize: 12,
}}
>
Try to enter the full name or part of it. It is possible
to use original language or the Latin alphabet.
</p>
}
required
error={!!fieldState.error}
{...otherFieldProps}
/>
)}
/>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<WSSelectBox
id="sanctions-form-residential-country"
label="Residential country"
name={'residentialCountry'}
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type={'text'}
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={3}>
<WSSelectBox
data={['Ten', 'Twenty']}
handleSelect={() => {}}
id="sanctions-form-initiator"
name={'initiator'}
label="Initiator"
type="text"
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={6}>
<WSSelectBox
id="sanctions-form-program"
label="Program"
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type="text"
name={'program'}
control={control}
/>
</Grid>
<Grid item xs={12} sm={6} md={6}>
<WSSelectBox
id="sanctions-form-list"
label="List"
data={['Ten', 'Twenty']}
handleSelect={() => {}}
type={'text'}
name={'list'}
control={control}
/>
</Grid>
</Grid>
<Grid
container
pt={{ xs: '20px', md: '30px' }}
rowSpacing="10px"
alignItems="center"
sx={{
[isMobile(theme)]: {
textAlign: 'center',
},
}}
justifyContent="left"
>
<Grid item xs={6} sm={'auto'}>
<Button
variant="contained"
color="primary"
sx={{
minWidth: '200px',
['#media (max-width:460px)']: {
minWidth: '120px',
},
}}
type="submit"
>
Search
</Button>
</Grid>
<Grid item xs={6} sm={'auto'}>
<Button
sx={{
minWidth: '200px',
color: '#3883FA',
['#media (max-width:460px)']: {
minWidth: '120px',
},
}}
type="submit"
>
Reset
</Button>
</Grid>
</Grid>
</form>
<Typography
variant="body2"
sx={{ fontSize: 17, color: '#121E3D', marginTop: '20px' }}
>
Use filters to start your search.
</Typography>
</FormProvider>
);
};
export default Entities;
SELECT BOX
import { TextField, MenuItem, styled, Select } from '#mui/material';
import { Controller, useForm } from 'react-hook-form';
export type SelectBoxProps = {
label: string;
id: string;
data: Array<string>;
handleSelect: VoidFunction;
type: string;
Control: () => {};
};
const SelectBox = styled(TextField)`
& .MuiOutlinedInput-root:focus {
&.Mui-focused fieldset {
border-bottom: none !important;
}
}
`;
const WSSelectBox = ({
label,
id,
data,
handleSelect,
name,
type,
control,
}) => {
return (
<>
<Controller
name={name}
render={({ field }) => (
<SelectBox
defaultValue=""
fullWidth
autoComplete="off"
id={id}
type={type}
label={label}
variant="outlined"
required
select
{...field}
>
{data.map((opt) => (
<MenuItem key={opt} value={opt}>
{opt}
</MenuItem>
))}
</SelectBox>
)}
control={control}
/>
</>
);
};
export default WSSelectBox;

Failed to load resource: the server responded with a status of 422 (Unprocessable Entity)

I'm facing this error when I want to request the backend i checked my backend code on postman it's fine but when i make the request from the front-end it gives that error to me i'm using redux and reac-reudx for my api request from the front-end
there is signup page
export default function Signup() {
const handleSubmit = (event) => {
event.preventDefault();
dispatch(signup(input))
};
const dispatch = useDispatch();
const navigate = useNavigate();
const [input, setinput] = useState('')
// it should be same as the name of the of input fields otherwise it will never be operational
const {Name,email,password}=input
const handlechange=(e)=>setinput({...input,[e.target.name]:e.target.value})
return (
<ThemeProvider theme={theme}>
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop:20,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Signup
</Typography>
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 3 }}>
<Grid container spacing={2}>
<Grid item xs={12}>
<TextField
autoComplete="given-name"
name="Name"
required
fullWidth
id="Name"
label="Name"
autoFocus
onChange={handlechange}
value={Name}
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
onChange={handlechange}
value={email}
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="new-password"
onChange={handlechange}
value={password}
/>
</Grid>
<Grid item xs={12}>
<FormControlLabel
control={<Checkbox value="allowExtraEmails" color="primary" />}
label="I want to receive inspiration, marketing promotions and updates via email."
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign Up
</Button>
<Grid container justifyContent="flex-end">
<Grid item style={{paddingRight:'90px'}}>
<Link to="/signup" variant="body2" style={{color:'blue'}}>
If your already have an account
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
</ThemeProvider>
my reducers page
const reducer = (signs = null, action) => {
switch (action.type) {
case SIGN:
return [...signs, action.payload];
default:
return signs;
}
}
here is my action page
export const signup = (formdata) => async (dispatch) => {
try {
const {data} = await api.signUp(formdata);
dispatch({ type: SIGN, payload: data });
console.log(data)
} catch (error) {
console.log(error);
}
};
export const signin = (formdata) => async (dispatch) => {
try {
const {data} = await api.signIn(formdata);
dispatch({ type: SIGN, payload: data });
} catch (error) {
console.log(error);
}
};

Material UI Avatar Image Upload

I managed it to make an Avatar chooser, but I don't know how to save the picture in Firebase or how to even save it as a Profile picture.
This is how it looks like:
This comes out if I click on the button:
I can choose a pic, but it just not saving it anywhere and also not displaying the picture in the avatar.
My code:
function Profile(props, navigation) {
const classes = useStyles();
const user = useUser(props.route.params.uid);
const [time, setTime] = useState("7:30");
const [timing, setTiming] = useState([]);
const [timeAfternoon, setTimeAfternoon] = useState("7:30");
const [timingAfternoon, setTimingAfternoon] = useState([]);
const [sickDaysStart, setSickDaysStart] = useState(Date.now());
const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
const [sickDaysConfirm, setSickDaysConfirm] = useState([]);
const [donwloadURL, setDownloadURL] = useState([]);
const onLogout = () => {
firebase.auth().signOut();
};
function handelSickDaysStart(e) {
setSickDaysStart(e.target.value);
}
function handelSickDaysEnd(e) {
setSickDaysEnd(e.target.value);
}
function handleTime(e) {
setTime(e.target.value);
}
function handleTimeAfternoon(e) {
setTimeAfternoon(e.target.value);
}
function delayMorning() {
db.collection("delayInTheMorning")
.doc()
.set({
time,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTiming([...timing, { time }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function delayAfternoon() {
db.collection("delayInTheAfternoon")
.doc()
.set({
timeAfternoon,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function sickDaysStartEnd() {
db.collection("DaysofSickness")
.doc()
.set({
sickDaysStart,
sickDaysEnd,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setSickDaysConfirm([
...sickDaysConfirm,
{ sickDaysStart, sickDaysEnd },
]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function isCurrentUserProfile() {
if (props.route.params.uid === firebase.auth().currentUser.uid) {
return true;
} else {
return false;
}
}
async function handleFileInputChange(e) {
const files = e.target.files;
const file = files[0];
const storage = firebase.storage();
const usersImageRef = storage
.ref()
.child(`users/${user.uid}/profilepicture.jpg`);
const snap = await usersImageRef.put(file);
const donwloadURL = await snap.ref.getDownloadURL();
setDownloadURL(donwloadURL);
await firebase.auth().currentUser.updateProfile({ photoURL: donwloadURL });
}
if (user === null) {
return <div className={classes.root} />;
}
return (
<ScrollView style={styles.root}>
<Container className={classes.div}>
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
onChange={handleFileInputChange}
/>
<label>
<IconButton>
<Avatar
src="../assets/ana.png"
style={{
margin: "10px",
width: "60px",
height: "60px",
}}
/>
</IconButton>
</label>
<Typography className={classes.text}> {user.name} </Typography>
<Typography className={classes.text}> {user.email} </Typography>
{isCurrentUserProfile() ? (
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onLogout()}
>
Logout
</Button>
) : null}
</Container>
<Card className={classes.div}>
{/* //Verspätung */}
<CardContent className={classes.cardBackGround}>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung{" "}
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTime(value);
}}
/>
<Button className={classes.cardBtn} onClick={() => delayMorning()}>
Absenden
</Button>
</Container>
</CardContent>
{/* //Krankenmledungen */}
<CardContent className={classes.cardBackGround}>
<Typography variant="h5" className={classes.cardTyp}>
Krankenmledungen
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="date"
label="Von"
type="date"
defaultValue="2021-09-14"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysStart(value);
}}
/>
<TextField
id="date"
label="bis"
type="date"
defaultValue="2021-09-20"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysEnd(value);
}}
/>
</Container>
<Button
className={classes.cardBtnKM}
onClick={() => sickDaysStartEnd()}
>
Absenden
</Button>
</CardContent>
{/* //Verspätung Abolung*/}
<CardContent className={classes.cardBackGround}>
<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
}}
onChange={(value) => {
handleTimeAfternoon(value);
}}
/>
<Button
className={classes.cardBtn}
onClick={() => delayAfternoon()}
>
Absenden
</Button>
</Container>
</CardContent>
</Card>
{/* <List> */}
{/* Verspätungs Liste */}
{timing.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list1}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung in der Früh ${item.time}`}
/>
</ListItem>
</List>
);
})}
{/* Krankmeldung */}
{timingAfternoon.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung bei der Abholung ${item.timeAfternoon}`}
/>
</ListItem>
</List>
);
})}
{/* Verspätungs Nachmittag */}
{sickDaysConfirm.map((item) => {
return (
<List className={classes.lists}>
<ListItem className={classes.list}>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Krankmeldung von ${item.sickDaysStart} bis ${item.sickDaysEnd}`}
/>
</ListItem>
</List>
);
})}
</ScrollView>
);
}
There is also a imagePicker from Expo, I was thinking of trying that but I'm just not sure.
If you want to change the profile picture of a user you can use this code:
import { getAuth, updateProfile } from "firebase/auth";
const auth = getAuth();
updateProfile(auth.currentUser, {
displayName: "User Name", photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(() => {
// Profile updated!
// ...
}).catch((error) => {
// An error occurred
// ...
});
You can find more info about it here.
To get the picture URL you would need to upload it to Firebase Storage and get the downloadURL:
import { getStorage, ref, uploadBytes, getDownloadURL } from "firebase/storage";
const storage = getStorage();
const storageRef = ref(storage, 'some-child');
// 'file' comes from the Blob or File API
uploadBytes(storageRef, file).then((snapshot) => {
console.log('Uploaded a blob or file!');
getDownloadURL(snapshot.ref).then((downloadURL) => {
console.log('File available at', downloadURL);
});
});
I would also change the input to not have multiple files to select. If you would share more of your code I can integrate those code snippets in your code in case you have problems with it.
UPDATE:
Here is the whole example. I see you use the old SDK so the example is with it:
function Profile(props, navigation) {
const classes = useStyles();
const user = useUser(props.route.params.uid);
const delay = DayandTime();
const [time, setTime] = useState("7:30");
const [timing, setTiming] = useState([]);
const [downloadurl, setDU] = useState("/images/example.jpg");
const [timeAfternoon, setTimeAfternoon] = useState("7:30");
const [timingAfternoon, setTimingAfternoon] = useState([]);
const [sickDaysStart, setSickDaysStart] = useState(Date.now());
const [sickDaysEnd, setSickDaysEnd] = useState(Date.now());
const [sickDaysConfirm, setSickDaysConfirm] = useState([]);
const onLogout = () => {
firebase.auth().signOut();
};
function handelSickDaysStart(e) {
setSickDaysStart(e.target.value);
}
function handelSickDaysEnd(e) {
setSickDaysEnd(e.target.value);
}
function handleTime(e) {
setTime(e.target.value);
}
function handleTimeAfternoon(e) {
setTimeAfternoon(e.target.value);
}
function delayMorning() {
db.collection("delayInTheMorning")
.doc()
.set({
time,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTiming([...timing, { time }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function delayAfternoon() {
db.collection("delayInTheAfternoon")
.doc()
.set({
timeAfternoon,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setTimingAfternoon([...timingAfternoon, { timeAfternoon }]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function sickDaysStartEnd() {
db.collection("DaysofSickness")
.doc()
.set({
sickDaysStart,
sickDaysEnd,
user,
})
.then(() => {
//If you wish to push the written data to your local state, you can do it here
setSickDaysConfirm([
...sickDaysConfirm,
{ sickDaysStart, sickDaysEnd },
]);
console.log("Documents saved succesfully");
})
.catch((err) => {
console.log(err);
});
}
function isCurrentUserProfile() {
if (props.route.params.uid === firebase.auth().currentUser.uid) {
return true;
} else {
return false;
}
}
if (user === null) {
return <div className={classes.root} />;
}
async function handleFileInputChange(e) {
const files = e.target.files;
const file = files[0];
const storage = firebase.storage();
const usersImageRef = storage
.ref()
.child(`users/${user.uid}/profilepicture.jpg`);
const snap = await usersImageRef.put(file);
const downloadURL = await snap.ref.getDownloadURL();
setDU(downloadURL);
await firebase.auth().updateProfile({ photoURL: downloadURL });
}
return (
<ScrollView style={styles.root}>
<Container className={classes.div}>
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
onChange={handleFileInputChange}
/>
<label htmlFor="contained-button-file">
<IconButton>
<Avatar
src="/images/example.jpg"
style={{
margin: "10px",
width: "60px",
height: "60px",
}}
/>
</IconButton>
</label>
<Typography className={classes.text}> {user.name} </Typography>
<Typography className={classes.text}> {user.email} </Typography>
{isCurrentUserProfile() ? (
<Button
className={classes.btn}
size="large"
variant="outlined"
onClick={() => onLogout()}
>
Logout
</Button>
) : null}
</Container>
<Card className={classes.div}>
{/* //Verspätung */}
<CardContent>
<Typography variant="h5" className={classes.cardTyp}>
{" "}
Verspätung{" "}
</Typography>
<Container className={classes.cardContainer}>
<TextField
id="time"
label="Zeit"
type="time"
defaultValue="07:30"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={(value) => {
handleTime(value);
}}
/>
<Button className={classes.cardBtn} onClick={() => delayMorning()}>
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="2021-09-14"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysStart(value);
}}
/>
<TextField
id="date"
label="bis"
type="date"
defaultValue="2021-09-20"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
onChange={(value) => {
handelSickDaysEnd(value);
}}
/>
</Container>
<Button
className={classes.cardBtnKM}
onClick={() => sickDaysStartEnd()}
>
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
}}
onChange={(value) => {
handleTimeAfternoon(value);
}}
/>
<Button
className={classes.cardBtn}
onClick={() => delayAfternoon()}
>
Absenden
</Button>
</Container>
</CardContent>
</Card>
<List>
{/* Verspätungs Liste */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung in der Früh ${delay}`}
/>
</ListItem>
{/* Verspätungs Krankmeldung */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Krankmeldung ${delay}`}
/>
</ListItem>
{/* Verspätungs Nachmittag */}
<ListItem>
<ListItemAvatar>
<Avatar></Avatar>
</ListItemAvatar>
<ListItemText
primary={user.name}
secondary={`Verspätung Nachmittag ${delay}`}
/>
</ListItem>
</List>
</ScrollView>
);
}
const mapStateToProps = (store) => ({
currentUser: store.userState.currentUser,
posts: store.userState.posts,
following: store.userState.following,
});
export default connect(mapStateToProps, null)(Profile);
const useStyles = makeStyles({
root: {
backgroundColor: "white",
},
div: {
marginTop: 20,
marginLeft: 15,
marginRight: 15,
backgroundColor: "white",
},
avatar: {
marginBottom: 10,
},
btn: {
marginTop: 10,
width: 250,
marginBottom: 30,
},
text: {
fontSize: 25,
marginTop: 10,
},
cardTyp: {
textAlign: "left",
paddingLeft: 13,
},
cardBtn: {
marginTop: 20,
marginLeft: 30,
},
cardBtnKM: {
marginTop: 20,
marginLeft: 10,
},
cardContainer: {
display: "flex",
},
});
const styles = StyleSheet.create({
root: {
backgroundColor: "white",
},
});

Material-UI Slider not drag when loading component from a switch

I am working on functionality where there is a set of radio buttons that change the state and determines which components should be active. I think I am close and the values all get set as they should but the slider will not slide, you have to click it in to position. I have a sandbox of what I am talking about here :
https://codesandbox.io/s/elated-banach-k1i4y?file=/src/Form.js
You will see that the radio reveals the appropriate slider. If you click the TEST button you can see that the correct value gets set to the object. I also added another Slider outside of the switch render method and you can see that works as expected.
Also here is the code I am using
import React, { Fragment, useState } from "react";
import {
Radio,
RadioGroup,
FormControlLabel,
FormControl,
Typography,
Slider,
Button
} from "#material-ui/core/";
export default function CreateForm() {
const defaultValues = {
a: 0,
b: 0,
c: 0
};
const [radioValue, setValue] = useState("");
const [activity, setActivity] = useState(defaultValues);
const handleRadioChange = (e) => {
const { value } = e.target;
setValue(value);
setActivity(defaultValues);
};
const handleSlider = (name) => (e, value) => {
setActivity({
...activity,
[name]: value
});
};
function RadioButtonsGroup() {
return (
<RadioGroup
aria-label="group"
name="group"
value={radioValue}
onChange={handleRadioChange}
row
>
<FormControlLabel
name="group"
value="a"
control={<Radio />}
label="A"
/>
<FormControlLabel
name="group"
value="b"
control={<Radio />}
label="B"
/>
</RadioGroup>
);
}
function test() {
console.log(activity);
}
function RenderSwitch(radioValue) {
switch (radioValue.value) {
case "a":
return <GetA />;
case "b":
return <GetB />;
default:
return <p>Select Radio</p>;
}
}
function GetA() {
return (
<React.Fragment>
<Typography id="discrete-slider" gutterBottom>
A
</Typography>
<Slider
value={activity.a}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={10}
marks
min={10}
max={120}
name="a"
onChange={handleSlider("a")}
style={{ marginBottom: "20px" }}
/>
</React.Fragment>
);
}
function GetB() {
return (
<Fragment>
<Typography id="discrete-slider" gutterBottom>
B
</Typography>
<Slider
value={activity.b}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={10}
marks
min={10}
max={120}
name="a"
onChange={handleSlider("b")}
style={{ marginBottom: "20px" }}
/>
</Fragment>
);
}
return (
<>
<form noValidate onSubmit={(e) => e.preventDefault()}>
<FormControl>
<RadioButtonsGroup />
<RenderSwitch value={radioValue} />
<Button
fullWidth
variant="contained"
color="primary"
type="submit"
onClick={test}
>
TEST
</Button>
<Typography
style={{ marginTop: "40px" }}
id="discrete-slider"
gutterBottom
>
One more to show how drag works here
</Typography>
<Slider
value={activity.c}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={10}
marks
min={10}
max={120}
name="c"
onChange={handleSlider("c")}
/>
</FormControl>
</form>
</>
);
}
You have to handle the sliders' state change inside their own elements like so (Sandbox):
const SliderA = () => {
const [activity, setActivity] = useState(0);
const handleChange = (event, newValue) => {
setActivity(newValue);
};
return (
<React.Fragment>
<Typography id="discrete-slider" gutterBottom>
A
</Typography>
<Slider
value={activity}
aria-labelledby="discrete-slider"
valueLabelDisplay="auto"
step={10}
marks
min={10}
max={120}
name="a"
onChange={handleChange}
style={{ marginBottom: "20px" }}
/>
</React.Fragment>
);
};

Resources