简体   繁体   中英

Uncontrolled input React

I have the following code:

import React, { Component } from 'react'
import axios from 'axios'
import Navbar from '../Navbar'
import { Avatar, TextField, Button, Container, CircularProgress } from '@material-ui/core'
import Alert from '@material-ui/lab/Alert'

class PrivateProfile extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            user: null,
            id: null,
            image: null,
            pp: null,
            username: 'AnonymousUser',
            showSuccess: false
        }
        this.handleChange = this.handleChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.handleFileChange = this.handleFileChange.bind(this)
    }
    componentDidMount() {
        axios.get('http://127.0.0.1:8000/users/profile')
        .then(res => {
            this.setState({ 
                user: res.data,
                id: res.data.id,
                username: res.data.username,
                pp: res.data.pp 
            })
        })
        .catch(err => console.log(err))
    }
    handleSubmit(e) {
        e.preventDefault()
        const fd = new FormData()
        fd.append('pp', this.state.image)
        fd.append('username', this.state.user.username)
        fd.append('email', this.state.user.email)
        fd.append('bio', this.state.user.bio)
        const d = {
            pp : this.state.image,
            username : this.state.user.username,
            email : this.state.user.email,
            bio : this.state.user.bio
        }
        console.log('d', d)
        console.log('fd', fd)
        axios.put(`http://127.0.0.1:8000/users/profile/update/${this.state.id}/`, fd, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })
        .then(res => {
            this.setState({
                user: res.data,
                id: res.data.id,
                pp: res.data.pp,
                image: null,
                username: res.data.username,
                showSuccess: true
            })
        })
        .catch(err => console.log(err))
    }
    handleChange(e) {
        this.setState({
            user: {
                [e.target.name]: e.target.value
            }
        })
    }
    handleFileChange(e) {
        this.setState({image: e.target.files[0]})
    }
    render() { 
        let message
        let alert
        if (this.state.user !== null) {
            if (!this.state.user.bio) {
                message = <h4>Please update your profile below.</h4>
            }
            if (this.state.showSuccess) {
                alert = <Alert action={<Button onClick={() => this.setState({showSuccess: false})}>Close</Button>} severity='success'>Profile Successfully Updated</Alert>
            }
            return ( 
                <div>
                    <Navbar />
                    <Container style={{background: '#f7f4e9'}}>
                        <div style={{height: '60px'}}></div>
                        <h2>Your Profile</h2>
                        <Avatar src={this.state.user.pp} alt={this.state.user.username} />
                        {message}
                        {alert}
                        <h4>Your data:</h4>
                        <form onSubmit={this.handleSubmit}>
                            <p>Profile Pic</p>
                            <input type="file" onChange={this.handleFileChange}/>
                            <br></br>
                            <br></br>
                            <TextField label='Username' name="username" onChange={this.handleChange} type="text" value={this.state.user.username} />
                            <br></br>
                            <br></br>
                            <TextField label='Email' name="email" onChange={this.handleChange} type="email" value={this.state.user.email} />
                            <br></br>
                            <br></br>
                            <TextField label='Bio' name="bio" onChange={this.handleChange} type="text" value={this.state.user.bio} />
                            <br></br>
                            <br></br>
                            <br></br>
                            <Button type="submit" value="submit">Update</Button>
                        </form>
                    </Container>
                </div>
            )
        } else {
            return <CircularProgress />
        }
    }
}

export default PrivateProfile

I get the error saying: Warning: A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Can someone help me fix it.

Since you're initializing state values with null and using it like value={this.state.user.username} , and update the state, you'll get such error:

Warning: A component is changing a controlled input of type text to be uncontrolled.

To control it's state, use it like:

value={this.state.user.username || ''}

As per my comment, you have issue here:

handleChange(e) {
  this.setState({
    user: {
     [e.target.name]: e.target.value
    }
  })
}

The user state will always change on your any input changes, you will need like:

handleChange(e) {
  this.setState({
    user: {
     ...this.state.user,
     [e.target.name]: e.target.value
    }
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM