简体   繁体   English

React失败的prop类型:没有onChange处理函数的值

[英]React Failed prop type: value without onChange handler

This is my form component: 这是我的form组件:

Form.jsx 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;

and this is my app component: 这是我的app组件:

App.jsx 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;

This is the error console is showing: 这是错误控制台显示的内容:

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)

I don't get it, though, because form change is being handled at <input> in the code above, like so: 但是,我不明白,因为上面的代码在<input>中处理了表单更改,如下所示:

onChange={this.props.handleFormChange}

so what am I missing? 那我想念什么? forms are not even accepting inputs. 表格甚至不接受输入。

You have fundamentally misunderstood the props concept in React components. 您从根本上误解了React组件中的props概念。 I will try to explain it with a more simplified version of your app. 我将尝试使用您的应用程序的更简化版本进行解释。 Lets take the form example. 让我们以表格为例。

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} />
  }

}

As you can see the App is going to render the Form component. 如您所见,应用程序将呈现Form组件。 Look at Focus point 1 and 2. In the first focus point its trying to access the local 'handleFormChange' function. 看一下焦点1和2。在第一个焦点中,它试图访问本地的'handleFormChange'函数。 And the 2nd one tries to call whatever the function that is provided by the parent via props. 第二个尝试调用父对象通过props提供的任何函数。

So what happened is that you are telling the 'Form' component to access the handleFormChange function which should have been provided by the parent as a "prop" ie this.props.handleFormChange. 因此,发生的事情是您要告诉“表单”组件访问handleFormChange函数,该函数应该由父级以“ prop”(即this.props.handleFormChange)提供。 So when the component is mounted React tries to bind this.props.handleFormChange to the onChange event of the input. 因此,在安装组件时,React尝试将this.props.handleFormChange绑定到输入的onChange事件。

But in your instance, the 'handleFormChange' prop in the component is not provided. 但是在您的实例中,组件中未提供“ handleFormChange”道具。 hence this.props.handleFormChange will be undefined resulting in that warning. 因此this.props.handleFormChange将未定义,从而导致该警告。

So to wire up any handlers that are within the Form component they should not be linked with 'this.props'. 因此,要连接Form组件的任何处理程序,它们不应与“ this.props”链接。 Whatever handlers that are accessed via props should be provided by the parent when initializing the component. 初始化组件时,父项应提供通过prop访问的任何处理程序。

Its because you are not passing any prop named as handleFormChange from App.jsx to the Form component. 这是因为您没有将任何名为handleFormChange道具从App.jsx传递给Form组件。

Instead, it's in your own Form component. 相反,它位于您自己的Form组件中。

So, just try this onChange={this.handleFormChange} 因此,只需尝试使用onChange={this.handleFormChange}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我应该如何避免这种“警告:道具类型失败:您在没有onChange处理程序的情况下为表单字段提供了一个value道具。” - How should I avoid this “Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler.” 失败的道具类型:您在没有“onChange”处理程序的情况下向表单字段提供了“已检查”道具 - Failed prop type: You provided a `checked` prop to a form field without an `onChange` handler 表单 propType 失败:您在没有 `onChange` 处理程序的情况下向表单字段提供了 `value` 道具 - Failed form propType: You provided a `value` prop to a form field without an `onChange` handler 使用事件传播时反应警告“您在没有 `onChange` 处理程序的情况下向表单字段提供了 `value` 道具...” - React warning "You provided a `value` prop to a form field without an `onChange` handler..." when using event propagation 在实际定义处理程序时,如何删除与在没有onChange处理程序的情况下对表单字段使用value道具相关的ReactJS警告? - How to remove ReactJS warning related to using a `value` prop to a form field without an `onChange` handler when the handler is actually defined? 警告:您在没有 `onChange` 处理程序的情况下为表单字段提供了 `checked` 属性 - Warning: You provided a `checked` prop to a form field without an `onChange` handler 道具类型失败:提供给“TextInput”React Native 的“对象”类型的无效道具“值” - Failed prop type: Invalid prop 'value' of type 'object' supplied to 'TextInput' React Native 打字稿反应<Select>onChange 处理程序类型错误 - Typescript React <Select> onChange handler type error 反应TypeScript 事件处理程序道具的正确类型 - React TypeScript | Correct Type for Event Handler Prop 道具类型失败:您向表单字段提供了“值”道具。 反应 - 引导 - Typehead - Failed prop type: You provided a `value` prop to a form field. React-Bootstrap-Typehead
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM