如何从父组件调用子组件功能?

时间:2019-03-16 10:26:00

标签: javascript reactjs

我有一个满足以下条件的输入字段组件:

首先关注焦点,直到该字段有效,然后再应用有效的类,否则不会发生任何事情

第一次模糊时,如果该字段无效,则应用一个无效的类。

在第一次模糊之后,一旦与该字段进行任何进一步的接触,只要该字段的值从有效变为无效,反之亦然,就会应用一个类。

要达到这个目的,我已经做到了:

import React, { Component } from "react";

class Input extends Component {
  constructor(props) {
    super(props);
    this.state = {
      touched: false,
      valid: false,
      focused: false,
      value: ""
    };

    this.handleFocus = this.handleFocus.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  handleFocus() {}

  handleBlur() {
    if (!this.state.touched) {
      this.setState({
        touched: true
      });
    } else if (this.state.touched) {
      this.setState({
        focused: true
      });
    }
  }

  handleChange(e) {
    const val = e.target.value

    this.setState({ value: val }, () => {
        this.validateField();
      }
    );
  }

  validateField() {
    const touched = this.state.touched;
    const focused = this.state.focused;
    const valid = this.state.valid;
    const value = this.state.value;

    if (value.length >= 5) {
      this.setState({
        valid: true,
        touched: true
      });
    } else {
      this.setState({ valid: false });
    }
  }

  render() {
    return (
      <div>
        <input
          id={this.props.id}
          name={this.props.name}
          type="text"
          className={`form-control ${styles["kyi-input"]} ${
            this.state.valid ? "is-valid" : ""
          } ${this.state.touched && !this.state.valid ? "is-invalid" : ""}`}
          required
          spellCheck="false"
          autoComplete="off"
          onFocus={this.handleFocus}
          onChange={this.handleChange}
          value={this.state.value}
          onBlur={this.handleBlur}
          placeholder={this.props.placeholder}
        />
      </div>
    );
  }
}

class Parent extends Component {

    handleInput(val, name) {
        // Can get value of input here
        this.setState({
          [name]: val
        });
    }

    render() {
        <Input placeholder="Test" onChange={(val) => {this.handleInput(val, 'inputName')}}/>    
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

它有效,但这意味着字段的状态位于子组件而不是父组件中。

输入字段的onBlur函数依赖于字段的状态。

有没有一种方法可以重构它,使输入状态位于父组件中,而onBlur函数位于子组件中?

1 个答案:

答案 0 :(得分:2)

我认为您应该在父组件中获得所有状态,还应该在父组件中获得所有修改状态的功能。这将使您拥有一个“单一事实来源”,它可以跟踪状态的变化并将其传递给所有子组件。 检出Lifting state up