为什么在使用prop将值传递给另一个组件时无法在react Input字段中连续键入

时间:2019-06-19 21:06:45

标签: javascript reactjs

我正在尝试通过props将值从一个组件传递到另一个。 父组件是InstructorLoginForm,子组件是InstructorLoginFormComponent

一切正常,但问题是我不能连续输入

我尝试键入username,它键入一个字母,然后失去对输入字段的关注,所以我必须再次单击输入字段并键入另一个(单个)字母,然后再次失去焦点 password字段也是如此。

她是我的父母InstructorLoginForm.jsx

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import InstructorProfile from "./instructor-profile";
import InstructorLoginFormComponent from "./instructor-login-form-component";

export default class InstructorLoginForm extends Component {
  constructor(props) {
    super(props);

    this.state = {
      username: "",
      password: ""
    };

    this.onChangeUsername = this.onChangeUsername.bind(this);
    this.onChangePassword = this.onChangePassword.bind(this);
    this.handleOnClick = this.handleOnClick.bind(this);
  }

  onChangeUsername(e) {
    this.setState({
      username: e.target.value
    });
  }

  onChangePassword(e) {
    this.setState({
      password: e.target.value
    });
  }

  handleOnClick (){
    e.preventDefault();
    this.props.history.push(`/instructor/${this.state.username}`);    
  }

  render() {
    return (
      <Router>
        <Switch>
          <Route
            exact
            path="/login"
            component={props => (
              <InstructorLoginFormComponent
                {...props}
                username = {this.state.username}
                password = {this.state.password}
                handleOnClick = {this.handleOnClick}
                onChangeUsername = {this.onChangeUsername}
                onChangePassword = {this.onChangePassword}
              />
            )}
          />
          <Route
            path={"/instructor/:instructorId"}
            component={InstructorProfile}
          />
        </Switch>
      </Router>
    );
  }
}

这是我的子组件InstructorLoginFormComponent.jsx

import React, { Component } from "react";
import { Link } from "react-router-dom";

export default class InstructorLoginFormComponent extends Component {
  constructor(props) {
    super(props);
  }

  componentDidMount(){
    console.log(this.props);
  }

  render() {
    return (
      <div className="container h-100" style={{ marginTop: 100 }}>
        <div className="d-flex justify-content-center h-100">
          <div className="user_card bg-dark">
            <div className="d-flex justify-content-center">              
            </div>
            <div
              className="d-flex justify-content-center form_container"
              style={{ marginTop: 0 }}
            >
              <form>
                <div className="input-group mb-3">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-user" />
                    </span>
                  </div>
                  <input
                    value={this.props.username}
                    onChange={this.props.onChangeUsername}
                    type="text"
                    name="username"
                    className="form-control input_user"
                    placeholder="username"
                  />
                </div>
                <div className="input-group mb-2">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-lock" />
                    </span>
                  </div>
                  <input
                    value={this.props.password}
                    onChange={this.props.onChangePassword}
                    type="password"
                    name="passwordbutton"
                    className="form-control input_user"
                    placeholder="password"
                  />
                </div>
                <div className="form-group">
                  <div className="custom-control custom-checkbox">
                    <input
                      type="checkbox"
                      className="custom-control-input"
                      id="customControlInline"
                    />
                    <label
                      className="custom-control-label"
                      htmlFor="customControlInline"
                      style={{ color: "#ffffff" }}
                    >
                      Remember me
                    </label>
                  </div>
                </div>
              </form>
            </div>

            <div className="d-flex justify-content-center mt-3 login_container">
              <button
                // to={`/instructor/${this.props.username}`}
                onClick={this.props.handleOnClick}
                type="button"
                className="btn login_btn bg-info"
              >
                Login
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

有人可以帮助我为什么会这样以及如何解决吗?

2 个答案:

答案 0 :(得分:3)

键入文本时,父组件的状态将更新并再次渲染函数调用。您使用

GROUP BY mmo.location_id, 3

它在每次渲染时调用<Route component={...} /> ,因此旧的子组件会卸载,而路由器会创建新的实例,焦点会丢失。 要解决此问题,请使用

React.createElement

它还为孩子提供{match,location,history}道具,但在父状态更改时不会卸载。

答案 1 :(得分:0)

很抱歉这样说,但这是糟糕的体系结构以及一些语法错误。 您应该在App.js文件中拥有所有路由,而在Component文件中应拥有其他所有路由(实际上应该是Container.js文件和Component.js文件,但要再等一次)。
您只需要一个onChange事件(请注意对函数结构的更改)。
以下行为应有其表现。
请注意handleOnClick应该有(e),应该抛出错误。
请注意,输入中的密码名称已从密码按钮更正为密码

App.js;

import React, { Component } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import InstructorProfile from "./instructor-profile";
import InstructorLoginFormComponent from "./instructor-login-form-component";

export default class App extends Component {

  render() {
    return (
      <Router>
        <Switch>
          <Route
            exact
            path="/login"
            component={InstructorLoginFormComponent }
          />

          <Route
            path={"/instructor/:instructorId"}
            component={InstructorProfile}
          />
        </Switch>
      </Router>
    );
  }
}

和InstructorLoginFormComponent;

import React, { Component } from "react";
import { Link } from "react-router-dom";

export default class InstructorLoginFormComponent extends Component {
  constructor(props) {
    super(props)

    this.state = {
      username: "",
      password: ""
    }
    this.onChange = this.onChange.bind(this)
    this.handleOnClick = this.handleOnClick.bind(this)
  }

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

  handleOnClick (e) {
    e.preventDefault()
    this.props.history.push(`/instructor/${this.state.username}`)    
  }


  render() {
    const { username, password } = this.state

    return (
      <div className="container h-100" style={{ marginTop: 100 }}>
        <div className="d-flex justify-content-center h-100">
          <div className="user_card bg-dark">
            <div className="d-flex justify-content-center">              
            </div>
            <div
              className="d-flex justify-content-center form_container"
              style={{ marginTop: 0 }}
            >
              <form>
                <div className="input-group mb-3">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-user" />
                    </span>
                  </div>
                  <input
                    value={username}
                    onChange={this.onChange}
                    type="text"
                    name="username"
                    className="form-control input_user"
                    placeholder="username"
                  />
                </div>
                <div className="input-group mb-2">
                  <div className="input-group-append">
                    <span className="input-group-text bg-info">
                      <i className="fa fa-lock" />
                    </span>
                  </div>
                  <input
                    value={password}
                    onChange={this.onChange}
                    type="password"
                    name="password"
                    className="form-control input_user"
                    placeholder="password"
                  />
                </div>
                <div className="form-group">
                  <div className="custom-control custom-checkbox">
                    <input
                      type="checkbox"
                      className="custom-control-input"
                      id="customControlInline"
                    />
                    <label
                      className="custom-control-label"
                      htmlFor="customControlInline"
                      style={{ color: "#ffffff" }}
                    >
                      Remember me
                    </label>
                  </div>
                </div>
              </form>
            </div>

            <div className="d-flex justify-content-center mt-3 login_container">
              <button
                // to={`/instructor/${this.props.username}`}
                onClick={this.props.handleOnClick}
                type="button"
                className="btn login_btn bg-info"
              >
                Login
              </button>
            </div>
          </div>
        </div>
      </div>
    );
  }
}