在创建/编辑表单上保留代码DRY

时间:2017-02-16 01:03:37

标签: javascript reactjs

我有一些输入在我的表单中用于创建和更新。我决定让它们成为一个组成部分。

// used for CRU on the event record
import React from 'react';

class Form extends React.Component {
  render() {
    return (
      <div className="slds-form">
        <div className="slds-form-element">
          <label className="slds-form-element__label">Assigned To</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.assigned = input} type="text" className="slds-input" disabled/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Related To</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.related = input} type="text" className="slds-input" disabled/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Location</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.location = input} type="text" className="slds-input" />
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Event Start</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.start = input} type="text" className="slds-input" />
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Event End</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.end = input} type="text" className="slds-input" />
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Contact</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.contact = input} type="text" className="slds-input" disabled/>
          </div>
        </div>
        <button type="button" className="slds-button slds-button--neutral">Cancel</button>
        <button type="submit" className="slds-button slds-button--brand">{this.props.buttonLabel}</button>
      </div>
    );
  }
}

export default Form;

然后我尝试在我的<Create />组件中使用此组件。

// used for Create on the event record
import React from 'react';
import Form from './Form';

class Create extends React.Component {

  createEvent(e) {
    console.log("createEvent() has fired.");
    e.preventDefault();
    const event = {
      assigned: this.assigned.value,
      related: this.related.value,
      location: this.location.value,
      start: this.start.value,
      end: this.end.value,
      contact: this.contact.value
    }
    console.log(event);
  }

  render() {
    return (
      <form onSubmit={(e) => this.createEvent(e)}>
        <Form buttonLabel="Create" />
      </form>
    );
  }
}

export default Create;

当我尝试点击<Create />组件上的“创建”按钮时,出现错误

Uncaught TypeError: Cannot read property 'value' of undefined
    at Create.createEvent (webpack:///./src/components/Event/Create.js?:42:32)
    at onSubmit (webpack:///./src/components/Event/Create.js?:59:27)
    at Object.ReactErrorUtils.invokeGuardedCallback (webpack:///./~/react/lib/ReactErrorUtils.js?:70:16)
    at executeDispatch (webpack:///./~/react/lib/EventPluginUtils.js?:89:21)
    at Object.executeDispatchesInOrder (webpack:///./~/react/lib/EventPluginUtils.js?:112:5)
    at executeDispatchesAndRelease (webpack:///./~/react/lib/EventPluginHub.js?:44:22)
    at executeDispatchesAndReleaseTopLevel (webpack:///./~/react/lib/EventPluginHub.js?:55:10)
    at Array.forEach (native)
    at forEachAccumulated (webpack:///./~/react/lib/forEachAccumulated.js?:25:9)
    at Object.processEventQueue (webpack:///./~/react/lib/EventPluginHub.js?:231:7)

然后我检查控制台,看到refs属于我的<Form />组件,而不是我的<Create />组件。

enter image description here enter image description here

有没有办法将我的子组件<Form />中的引用传递给其父组<Create />

1 个答案:

答案 0 :(得分:1)

那是很多refs!好消息,你真的根本不需要它们。作为一个非常一般的规则,如果您正在与不“理解”React(d3,Greensock,TinyMCE等)的外部库进行交互,那么您应该只使用refs。

uncontrolled方式处理它可以像:

const User = (props) => (
  <div>
    <input name="foo" className="form-control" />
    <input name="foo2" className="form-control" />
    <button type="submit" className="btn btn-primary">{props.buttonLabel}</button>
  </div>
);

class App extends React.Component {

  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

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

  onSubmit(e) {
    e.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <div className="container">
        <br />
        <form onChange={this.onChange} onSubmit={this.onSubmit}>
          <User buttonLabel="Create"/>
        </form>
      </div>
    );
  }
};


ReactDOM.render(<App />, document.getElementById('app'));

Codepen示例: http://codepen.io/cjke/pen/zNXxga?editors=0010