[英]How should I avoid this “Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.”
[英]React Failed prop type: value without onChange handler
這是我的form
組件:
Form.jsx
import React, { Component } from 'react';
import axios from 'axios';
import { Redirect } from 'react-router-dom';
class Form extends Component {
constructor (props) {
super(props);
this.state = {
formData: {
restaurant: '',
username: '',
email: '',
password: ''
}
};
this.handleUserFormSubmit = this.handleUserFormSubmit.bind(this);
this.handleFormChange = this.handleFormChange.bind(this);
};
componentDidMount() {
this.clearForm();
};
componentWillReceiveProps(nextProps) {
if (this.props.formType !== nextProps.formType) {
this.clearForm();
};
};
clearForm() {
this.setState({
formData: {restaurant: '', username: '', email: '', password: ''}
});
};
handleFormChange(event) {
const obj = this.state.formData;
obj[event.target.name] = event.target.value;
this.setState(obj);
};
handleUserFormSubmit(event) {
event.preventDefault();
const formType = this.props.formType
const data = {
restaurant: this.state.formData.restaurant,
email: this.state.formData.email,
password: this.state.formData.password
};
if (formType === 'register') {
data.username = this.state.formData.username
};
const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/auth/${formType}`;
axios.post(url, data)
.then((res) => {
this.clearForm();
this.props.loginUser(res.data.auth_token);
})
.catch((err) => { console.log(err); });
};
render() {
if (this.props.isAuthenticated) {
return <Redirect to='/' />;
};
return (
<div>
{this.props.formType === 'Login' &&
<h1 className="title is-1">Log In</h1>
}
{this.props.formType === 'Register' &&
<h1 className="title is-1">Register</h1>
}
<hr/><br/>
<form onSubmit={(event) => this.handleUserFormSubmit(event)}>
{this.props.formType === 'Register' &&
<div className="field">
<input
name="restaurant"
className="input is-medium"
type="text"
placeholder="Enter your restaurant name"
required
value={this.state.formData.restaurant}
onChange={this.props.handleFormChange}
/>
</div>
}
<div className="field">
<input
name="username"
className="input is-medium"
type="text"
placeholder="Enter a username"
required
value={this.state.formData.username}
onChange={this.props.handleFormChange}
/>
</div>
<div className="field">
<input
name="email"
className="input is-medium"
type="email"
placeholder="Enter an email address"
required
value={this.state.formData.email}
onChange={this.props.handleFormChange}
/>
</div>
<div className="field">
<input
name="password"
className="input is-medium"
type="password"
placeholder="Enter a password"
required
value={this.state.formData.password}
onChange={this.props.handleFormChange}
/>
</div>
<input
type="submit"
className="button is-primary is-medium is-fullwidth"
value="Submit"
/>
</form>
</div>
)
};
};
export default Form;
這是我的app
組件:
App.jsx
import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import axios from 'axios';
import UsersList from './components/UsersList';
import About from './components/About';
import NavBar from './components/NavBar';
import Form from './components/Form';
import Logout from './components/Logout';
import UserStatus from './components/UserStatus';
class App extends Component {
constructor() {
super();
this.state = {
users: [],
title: 'Test.io',
isAuthenticated: false,
};
this.logoutUser = this.logoutUser.bind(this);
this.loginUser = this.loginUser.bind(this);
};
componentWillMount() {
if (window.localStorage.getItem('authToken')) {
this.setState({ isAuthenticated: true });
};
};
componentDidMount() {
this.getUsers();
};
getUsers() {
axios.get(`${process.env.REACT_APP_WEB_SERVICE_URL}/users`)
.then((res) => { this.setState({ users: res.data.data.users }); })
.catch((err) => { });
};
logoutUser() {
window.localStorage.clear();
this.setState({ isAuthenticated: false });
};
loginUser(token) {
window.localStorage.setItem('authToken', token);
this.setState({ isAuthenticated: true });
this.getUsers();
};
render() {
return (
<div>
<NavBar
title={this.state.title}
isAuthenticated={this.state.isAuthenticated}
/>
<section className="section">
<div className="container">
<div className="columns">
<div className="column is-half">
<br/>
<Switch>
<Route exact path='/' render={() => (
<UsersList
users={this.state.users}
/>
)} />
<Route exact path='/about' component={About}/>
<Route exact path='/register' render={() => (
<Form
formType={'Register'}
isAuthenticated={this.state.isAuthenticated}
loginUser={this.loginUser}
/>
)} />
<Route exact path='/login' render={() => (
<Form
formType={'Login'}
isAuthenticated={this.state.isAuthenticated}
loginUser={this.loginUser}
/>
)} />
<Route exact path='/logout' render={() => (
<Logout
logoutUser={this.logoutUser}
isAuthenticated={this.state.isAuthenticated}
/>
)} />
<Route exact path='/status' render={() => (
<UserStatus
isAuthenticated={this.state.isAuthenticated}
/>
)} />
</Switch>
</div>
</div>
</div>
</section>
</div>
)
}
};
export default App;
這是錯誤控制台顯示的內容:
index.js:1446 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.
in input (at Form.jsx:72)
in div (at Form.jsx:71)
in form (at Form.jsx:69)
in div (at Form.jsx:61)
in Form (at App.jsx:66)
in Route (at App.jsx:65)
in Switch (at App.jsx:58)
in div (at App.jsx:56)
in div (at App.jsx:55)
in div (at App.jsx:54)
in section (at App.jsx:53)
in div (at App.jsx:48)
in App (at src/index.js:9)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.js:8)
但是,我不明白,因為上面的代碼在<input>
中處理了表單更改,如下所示:
onChange={this.props.handleFormChange}
那我想念什么? 表格甚至不接受輸入。
您從根本上誤解了React組件中的props概念。 我將嘗試使用您的應用程序的更簡化版本進行解釋。 讓我們以表格為例。
class Form extends Component {
handleFormChange(){
console.log("This is the form change function inside -Form-");
}
render(){
return(
<div>
<input
name="email"
type="text"
value={this.state.email}
onChange={this.handleFormChange} // Focus point 1 - Calls local function
/>
<input
name="username"
type="text"
value={this.state.username}
onChange={this.props.handleFormChange} // Focus point 2 - Calls function passed down via props
/>
</div>
);
}
}
class App extends Component {
handleFormChange(){
console.log("This is the form change function inside -App-");
}
render(){
return <Form handleFormChange={this.handleFormChange} />
}
}
如您所見,應用程序將呈現Form組件。 看一下焦點1和2。在第一個焦點中,它試圖訪問本地的'handleFormChange'函數。 第二個嘗試調用父對象通過props提供的任何函數。
因此,發生的事情是您要告訴“表單”組件訪問handleFormChange函數,該函數應該由父級以“ prop”(即this.props.handleFormChange)提供。 因此,在安裝組件時,React嘗試將this.props.handleFormChange綁定到輸入的onChange事件。
但是在您的實例中,組件中未提供“ handleFormChange”道具。 因此this.props.handleFormChange將未定義,從而導致該警告。
因此,要連接Form組件內的任何處理程序,它們不應與“ this.props”鏈接。 初始化組件時,父項應提供通過prop訪問的任何處理程序。
這是因為您沒有將任何名為handleFormChange
道具從App.jsx
傳遞給Form組件。
相反,它位於您自己的Form
組件中。
因此,只需嘗試使用onChange={this.handleFormChange}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.