2

I had button in app.js and i wanna using event onSubmit from another function. But, when I'm trying it - nothing happens.

App.js

import React, { Component } from 'react';

import Publish from './Publish';

class App extends Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
        <div>
          <form onSubmit={Publish.onSubmit}>
              <button></button>
          </form>
        </div>
    );
  }
}

export default App;

Publish.js

import React, { Component } from 'react';
  import web3 from './web3';
  import auth from './multiauth';

  class Publish extends Component {
    constructor(props){
      super(props);
      this.state = {
        // some data
       };
    }

   componentDidMount(){
      fetch('url')
        .then(res => res.json())
        .then(json => {
          this.setState({
            //some data
          })
        })
    }

    onSubmit = async (event)=>{
        //some functional
  }

  export default Publish;

When Publish function onSubmit was in App it worked. But now, when I push the button nothing happens. How can i fix it?

Rohan Dhar
  • 1,827
  • 1
  • 10
  • 21
Hiroyasu
  • 83
  • 1
  • 6
  • 1
    Does `onSubmit` need to be a component method? Can it be a function in a module imported by `Publish` and `App`? – stealththeninja Dec 02 '18 at 05:47
  • @stealththeninja Yes, in module i need to have fetch and using after this onSubmit (example: 3 button with 3 different events). – Hiroyasu Dec 02 '18 at 06:05

2 Answers2

2

Publish is a class, not an instance, so there is no Publish.onSubmit - onSubmit is a class field, not a static method.

If onSubmit was a normal method, it would be a property of Publish.prototype, and you could use

<form onSubmit={Publish.prototype.onSubmit}>

You would only be able to use

<form onSubmit={Publish.onSubmit}>

if onSubmit were static (and thereby a property of the class itself), for example:

static onSubmit() {
  // do something
}

To make onSubmit a normal method, change its syntax to

onSubmit() {
  // do something
}

If you instantiate Publish, and you need this to refer to the instance inside onSubmit, then you would also need to .bind the function inside the constructor.

Live snippet:

class Publish extends React.Component {
  onSubmit(event) {
    event.preventDefault();
    console.log('submit running');
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
        <div>
          <form onSubmit={Publish.prototype.onSubmit}>
              <button>button</button>
          </form>
        </div>
    );
  }
}

// Render it
ReactDOM.render(
  <App />,
  document.getElementById("react")
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • So sad, but
    doesn't work :(
    – Hiroyasu Dec 02 '18 at 06:01
  • 1
    @Hiroyasu It should. BTW, what're you trying to do there also matters. Simply logging something should just work fine. – Bhojendra Rauniyar Dec 02 '18 at 06:03
  • @BhojendraRauniyar I'm trying to connect with MetaMask. In one file (app.js) all this code is working, but i even try add console.log("error") in Publish, it's nothing to help me. I think button just doesn't see events, but don't know why – Hiroyasu Dec 02 '18 at 06:08
  • @Hiroyasu not pretty sure, but you may try another option as far as possible as I mentioned in my post. – Bhojendra Rauniyar Dec 02 '18 at 06:10
  • @BhojendraRauniyar I trying add static, but nothing happens. My page just update and all. Something wrong, but anyway thanks – Hiroyasu Dec 02 '18 at 06:17
  • 1
    @Hiroyasu My mistake, `onSubmit` is a *class field*, not a *normal method*, so it's not on the prototype - see edit with live snippet – CertainPerformance Dec 02 '18 at 06:18
  • @CertainPerformance Does snippet working? I try this, but anyway - nothing. Where i need use bind(this) in class? – Hiroyasu Dec 02 '18 at 06:28
  • @Hiroyasu The snippet is working on both Chrome and FF for me. In the constructor, use `this.onSubmit = this.onSubmit.bind(this)` *if* you need `this` to refer to the `Publish` instance inside `onSubmit` (but if you need that, it seems quite strange to use `onSubmit` outside of the class) – CertainPerformance Dec 02 '18 at 06:31
2

This is not how you should do in react. Obviously, as pointed out in another answer, you can use:

<form onSubmit={Publish.prototype.onSubmit}>

Or, just export the function and use that.

But implementing like this would cost heavily for you. For example, it will be difficult to maintain the states. So, I would suggest you to provide a parent wrapper and in that supply the props for event handlers like:

<ParentComponent onSubmit={this.onSubmit}>

And in the child component, hook that event. For example:

<ChildComponent onSubmit={this.props.onSubmit}>

For further help, you may look into another post: call parent method in child component

Hope, this makes sense!

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231