React <Switch>不会更新或更改其状态

时间:2020-10-31 16:05:08

标签: javascript reactjs react-native react-router jsx

我正在学习的同学反应过来,并且有一个表格可以编辑书籍的详细信息。我在后端使用django。我无法更新switch这本电子书以根据是否有电子书来打开和关闭它。该开关工作正常,但是数据库中没有任何数据被更改。我对如何使用交换机感到困惑,并且看到很多资源在说不同的东西,这很难理解。其余字段正在正确更新。有人可以告诉我我必须对此switch进行哪些更改才能使其正常工作吗?

代码

import React, {useEffect, useState} from 'react'
import axiosInstance from '../../axios';
import { useForm, Controller } from 'react-hook-form';

//MaterialUI
import Button from '@material-ui/core/Button';
import CssBaseline from '@material-ui/core/CssBaseline';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Switch from '@material-ui/core/Switch';
import Select from '@material-ui/core/Select';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';


const useStyles = makeStyles((theme) => ({
    paper: {
        marginTop: theme.spacing(8),
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
    },
    bookformbody: {
        display: "flex",
        backgroundColor: "#ffff",
        height: "100vh",
    },
    form: {
        width: '100%', // Fix IE 11 issue.
        marginTop: theme.spacing(3),
    },
    submit: {
        margin: theme.spacing(3, 0, 2),
    },
}));


function BookEdit() {    
    const initialFormData = Object.freeze({
        id: '',
        summary: '',
        published_date: '',
        e_book: false,
    });

    const [formData, updateFormData] = useState(initialFormData);

    useEffect(() => {
        axiosInstance.get('api/books/details/view/').then((res) => {
            updateFormData({
                ...formData,
                ['summary']: res.data.summary,
                ['published_date']: res.data.published_date,
                                ['e_book']: res.data.e_book,

            });
            console.log(res.data);
        });
    }, [updateFormData]);

    const handleChange = (e) => {
        if(e.target.name === "e_book"){
             return(
                 updateFormData({
                     ...formData,
                     [e.target.name]: e.target.checked
                 })
                
             )
        }   
        updateFormData({
            ...formData,         
            // Trimming any whitespace
            [e.target.name]: e.target.value
        });
    };


    const onSubmit = (data) =>{
        let formData = new FormData();

        formData.append('summary', data.summary);
        formData.append('published_date', data.published_date);
        formData.append('e_book', data.e_book);

        axiosInstance.put('api/books/details/edit/', formData);

    } ;
    
    const classes = useStyles();
    const { register, handleSubmit, control, errors } = useForm();

    return (
        <>
            <Header />
            <div className={classes.bookformbody}>
                <SideBar />
                <Container component="main" maxWidth="sm">
                    <CssBaseline />
                    <div className={classes.paper}>
                        <Typography component="h1" variant="h5">
                            Edit Book Details
                        </Typography>
                        <form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}>
                            <Grid container spacing={2}>
                                <Grid item xs={12}>
                                    <TextField
                                        variant="outlined"
                                        required
                                        fullWidth
                                        id="summary"
                                        label="Book Summary"
                                        name="summary"
                                        autoComplete="summary"
                                        value={formData.summary}
                                        onChange={handleChange}
                                        inputRef={register({maxLength: 1000})}
                                        multiline
                                        rows={4}
                                    />
                                </Grid>

                                <Grid item xs={12}>
                                    <TextField
                                        variant="outlined"
                                        required
                                        fullWidth
                                        type="date"
                                        label="Published Date"
                                        name="published_date"
                                        autoComplete="published_date"
                                        value={formData.published_date}
                                        onChange={handleChange}
                                        inputRef={register({required: true})}
                                        InputLabelProps={{
                                            shrink: true,
                                          }}
                                    />
                                </Grid>

                                <Grid item xs={12}>
                                    <InputLabel id="e-book-switch">E-Book</InputLabel>
                                        <Controller
                                            name="e_book"
                                            control={control}
                                            as={
                                                <Switch size="small"
                                                    id="e-book-switch" 
                                                    type="checkbox"
                                                    name="e_book"
                                                    onChange={handleChange} 
                                                    // inputRef={register}
                                                    value={formData.e_book}
                                                    checked={formData.e_book}
                                                />
                                            }
                                        />
                                </Grid>
                            </Grid>
                            <Button
                                type="submit"
                                fullWidth
                                variant="contained"
                                color="primary"
                                className={classes.submit}
                            >
                                Update
                            </Button>
                        </form>
                    </div>
                </Container>
            </div>
        </>
    )
}

export default BookEdit;

2 个答案:

答案 0 :(得分:1)

您正在BookEdit()的开头将值初始化为字符串。尝试像这样设置initialFormData

const initialFormData = Object.freeze({
        id: '',
        summary: '',
        published_date: '',
        e_book: false,
    });

答案 1 :(得分:0)

您正在将道具直接传递给Switch,但是您应该做的是使用Controller道具,然后Controller会将其传递给Switch:

<Controller as={Switch} value={formData.e_book} ... />

否则,您需要使用渲染,而不要使用 实际上,这里描述的很好: https://react-hook-form.com/api/#Controller


更新

以下是沙盒,它可以很好地完成上述更改-https://codesandbox.io/s/kind-nash-s94v0

我在那里所做的只是这个:

  <Controller
  name="e_book"
  control={control}
  render={(props) => {
   return (
     <Switch
      size="small"
      id="e-book-switch"
      type="checkbox"
      name="e_book"
      onChange={handleChange}
      // inputRef={register}
      value={formData.e_book}
      checked={formData.e_book}
    />
   );
}}

/>