Strategy/Best Practice for calling this.setState outside a React.Component?

I have a lot of forms that call a failure or success function based on the response from my meteor methods. Not all, but many of these situations my failure/success functions are exactly the same. But I’m not 100% the best way to abstract this out because I often call this.setState inside the failure/success functions… and I’m not sure how to abstract it.



class AddItemForm extends React.Component {
	constructor(props){
		super(props);
		this.state = { loading: false }
	    this.handleSubmit = this.handleSubmit.bind(this);
	}
	handleSubmit(e, formData) {
	    e.preventDefault();

	    this.setState({loading: true}); //set loading spinner on button

	    const failure = (error) => {
	      if (error) { message.error(error, 3); }
	      this.setState({loading: false});
	    }

	    const success = () => {
	      	message.success('item added!!', 3);
	        this.setState({loading: false});
	    }

            Meteor.call('myFormSubmitMethod', formData, function(error, response){
                  if (error) { return failure(error.reason); }
                 return success();
            });

	}
	render(){

		return (
			<Form onSubmit={this.handleSubmit} >
			   <FormInput  label='Text Input' />
	                  <Button loading={this.state.loading} label={!this.state.loading ? 'Add Item' : 'Add...'} />
	               </Form>
		);
		
	}
}

In reality theres more happening in the success/failure functions, but I’d like something like this but unsure how to get back to calling this.setState without adding a callback, which seems like a massive chunk of code to have to add.


          const failure = (error) => {
	      if (error) { message.error(error, 3); }
	      this.setState({loading: false});
	    }

	    const success = () => {
	      	message.success('item added!!', 3);
	        this.setState({loading: false});
	    }

class AddItemForm extends React.Component {
	constructor(props){
		super(props);
		this.state = { loading: false }
	    this.handleSubmit = this.handleSubmit.bind(this);
	}
	handleSubmit(e, formData) {
	    e.preventDefault();

	    this.setState({loading: true}); //set loading spinner on button


            Meteor.call('myFormSubmitMethod', formData, function(error, response){
                  if (error) { return failure(error.reason); }
                 return success();
            });

	}
	render(){

		return (
			<Form onSubmit={this.handleSubmit} >
			   <FormInput  label='Text Input' />
	                  <Button loading={this.state.loading} label={!this.state.loading ? 'Add Item' : 'Add...'} />
	               </Form>
		);
		
	}
}

this was helpful:

I only use stateless component.
WIth state, i don’t really see what advantage has React over Blaze.