score:21

Accepted answer

You can curry the function

handleSubmit: text => event => {
  event.preventDefault()
  console.log(text)
}

<form onSubmit={this.handleSubmit('react!!!')}>
  ...

Equivalent ES5 code

handleSubmit: function(text) {
  return function(event) {
    event.preventDefault()
    console.log(text)
  }.bind(this)
}

Your code is weird though because you're mixing ES6 and ES5 styles. If you're using ES6 imports, you might as well use ES6 in the rest of your code

import {Component} from 'react'

class NewForm extends Component {
  handleSubmit (text) {
    return event => {
      event.preventDefault()
      console.log(text)
    }
  }
  render() {
    return (
      <form onSubmit={this.handleSubmit('react!!!')}>
        <input type="text">
      </form>
    }
  }
}

export default NewForm

Or better, since your Component doesn't use any state, you can use a Stateless Functional Component

import {Component} from 'react'

const handleSubmit = text=> event=> {
  event.preventDefault()
  console.log(text)
}

const NewForm = props=> (
  <form onSubmit={handleSubmit('react!!!')}>
    <input type="text">
  </form>
)

export default NewForm

score:8

Yes, but you shouldn't do it. What you are currently doing is saying 'set the onSubmit handler to being the result of calling this.handleSubmit('react!!!')'. What would work instead is to go:

<form onSubmit={e => this.handleSubmit(e, "react!!!")}>

which is of course just the short form of saying:

<form onSubmit={function(e) { this.handleSubmit(e, "react!!!"); }}>

However, although this will work, what this is doing is defining a new anonymous function every time render is called. Render can be called often, so this will end up with a bunch of new functions being created all the time, which can cause perf issues as they need to be garbage collected and cleaned up.

What is better is to have a function which is capable of finding the data you need on its own. There are 2 different ways which I use to address this:

  • Either store the relevant data in props, so that it can be pulled out from this.props
  • Or, store the relevant data in the DOM (using HTML 5 data attributes), and then pull them out using javascript. Since you are given the event target in the event handler that is called, you can use it to pull out any data attributes you have stored. For example you might declare your form like this:

    <form data-somefield={something.interesting} onSubmit={this.handleSubmit}>

which you could access in handleSubmit by going:

handleSubmit: function(e) {
    console.log(e.target.dataset.somefield);
}

The caveat there being that a) storing data in the DOM like this doesn't feel very idiomatic React, and b) if you use this for onClick events with nested elements, you might find that you have to climb up the DOM hierarchy to find where your data is stored. As an example if you have a div with a data attribute and an onClick but it contains a span and an image, when you click the image it's possible that is what the onClick handler will see as it's target element, meaning you'd have to go up to the parent to find the div with the data attribute you're looking for.

So it's probably best to just include the data you want in your component's props and pull it out from there in your event handler.


Related Query

More Query from same tag