Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

reactjs - Use state or refs in React.js form components?

I am starting with React.js and i want to do a simple form but in the documentation I have found two ways of doing it.

The first one is using Refs:

var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = React.findDOMNode(this.refs.author).value.trim();
    var text = React.findDOMNode(this.refs.text).value.trim();
    if (!text || !author) {
      return;
    }
    // TODO: send request to the server
    React.findDOMNode(this.refs.author).value = '';
    React.findDOMNode(this.refs.text).value = '';
    return;
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
});

And the second one is using state inside the React component:

var TodoTextInput = React.createClass({
  getInitialState: function() {
    return {
      value: this.props.value || ''
    };
  },

  render: function() /*object*/ {
    return (
      <input className={this.props.className}
      id={this.props.id}
      placeholder={this.props.placeholder}
      onBlur={this._save}
      value={this.state.value}
      />
    );
  },

  _save: function() {
    this.props.onSave(this.state.value);
    this.setState({value: ''
  });
});

I can't see the pros and cons of the two alternatives, if some exists. Thanks.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The short version: avoid refs.


They're bad for maintainability, and lose a lot of the simplicity of the WYSIWYG model render provides.

You have a form. You need to add a button that resets the form.

  • refs:
    • manipulate the DOM
    • render describes how the form looked 3 minutes ago
  • state
    • setState
    • render describes how the form looks

You have an CCV number field in an input and some other fields in your application that are numbers. Now you need to enforce the user only enters numbers.

  • refs:
    • add an onChange handler (aren't we using refs to avoid this?)
    • manipulate dom in onChange if it's not a number
  • state
    • you already have an onChange handler
    • add an if statement, if it's invalid do nothing
    • render is only called if it's going to produce a different result

Eh, nevermind, the PM wants us to just do a red box-shadow if it's invalid.

  • refs:
    • make onChange handler just call forceUpdate or something?
    • make render output based on... huh?
    • where do we get the value to validate in render?
    • manually manipulate an element's className dom property?
    • I'm lost
    • rewrite without refs?
    • read from the dom in render if we're mounted otherwise assume valid?
  • state:
    • remove the if statement
    • make render validate based on this.state

We need to give control back to the parent. The data is now in props and we need to react to changes.

  • refs:
    • implement componentDidMount, componentWillUpdate, and componentDidUpdate
    • manually diff the previous props
    • manipulate the dom with the minimal set of changes
    • hey! we're implementing react in react...
    • there's more, but my fingers hurt
  • state:
    • sed -e 's/this.state/this.props/' 's/handleChange/onChange/' -i form.js

People think refs are 'easier' than keeping it in state. This may be true for the first 20 minutes, it's not true in my experience after that. Put your self in a position to say "Yeah, I'll have it done in 5 minutes" rather than "Sure, I'll just rewrite a few components".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...