首页 > 解决方案 > 不受控制的输入反应

问题描述

我有以下代码:

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

我收到错误消息:警告:组件正在将文本类型的受控输入更改为不受控制。输入元素不应从受控切换到不受控(反之亦然)。决定在组件的生命周期内使用受控输入元素还是不受控输入元素。

有人可以帮我解决它。

标签: javascriptreactjs

解决方案


由于您使用 null 初始化状态值并像 一样使用它value={this.state.user.username}并更新状态,因此您将收到这样的错误:

警告:组件正在将文本类型的受控输入更改为不受控制。

要控制它的状态,可以像这样使用它:

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

根据我的评论,您在这里有问题:

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

用户状态将始终随着您的任何输入更改而更改,您将需要:

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

推荐阅读