0

From my landing page I am sending function to my search bar page.

LandingPage.js

export default class LandingPage extends React.Component {

   onSearchSubmit(term){
    console.log(term);
   }

    render() {
        return (
            <div>
            <div><SearchBar onSubmit = {this.onSearchSubmit} /></div>
            </div>
            ......

SearchBar.js

export default class SearchBar extends React.Component{

    state = {term: ''};

    onFormSubmit = event => {
        event.preventDefault();

        this.props.onSubmit(this.state.term);
    };

    render(){
        return(
            <div>
                <div className="container">

                    <div className="searchBar mt-5">
                        <form onSubmit={this.onFormSubmit}>
                            <div className="form-group">
                            <label for="search">Image search</label>
                                <input 
                                    type="text" 
                                    className="form-control" 
                                    placeholder="Search..." 
                                    value = {this.state.term}
                                    onChange={e => this.setState({term: e.target.value})}
                                />
                            </div>
                        </form>
                    </div>
                </div>

            </div>
        )
    }
}

My landing page (in this case parent) is on http://localhost:3000/ and when I type something in search bar on landing page it works just fine.

But when I go to http://localhost:3000/searchbar and type there I get following error

Uncaught TypeError: _this.props.onSubmit is not a function

UPDATE:

I have tried with adding binding and it's still not working. It works if I search the search bar on landing page like this.

enter image description here

But my question is if I go to only search bar page which is on http://localhost:3000/searchbar

enter image description here

separate of landing page which is on http://localhost:3000/ can I send data back?

I am still getting same error.

My question is is this even possible with ReactJS to send data back to parent page from child page on different URL?

user9347049
  • 1,927
  • 3
  • 27
  • 66

4 Answers4

2

This is an issue related to scope of this keyword in event callbacks. To overcome this you need to bind your functions in your component's constructor. Check official documents at React website: https://reactjs.org/docs/handling-events.html

You can solve your problem by adding following binding in your constructor.

// This binding is necessary to make `this` work in the callback
this.onFormSubmit = this.onFormSubmit.bind(this);
laltin
  • 1,134
  • 12
  • 20
2

issue is with your onSearchSubmit scope.

for that you have 2 options.

bind onSearchSubmit function in constructor like this

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

second option without using scope binding : change onSearchSubmit to arrow function.

export default class LandingPage extends React.Component {

  onSearchSubmit = term => {
    console.log(term);
  }

  render() {
    return (
        <div>
        <div><SearchBar onSubmit = {this.onSearchSubmit} /></div>
        </div>
        ......
Dhaval
  • 1,393
  • 5
  • 29
  • 55
1

To preserve your style, make your onSearchSubmit function an arrow function:

  onSearchSubmit = term => {
    console.log(term);
  }

Here you can find why should you use an arrow function there or what is the alternative (binding this): React.js and arrow functions vs normal functions [duplicate] Ask

Miklos
  • 21
  • 1
  • 5
  • Yes, I have tried that and I am still getting same error... I wander is it even possible to do so as I wrote in my update on my question. – user9347049 Feb 28 '19 at 14:36
  • How does your routing look like? On `/searchbar` route do you pass the SerachBar component an onSubmit handler function? And could you post your error messages? – Miklos Feb 28 '19 at 15:31
  • I have found solution that worked for me. I restructured my app and used routing to pass data between my components. Please check it. :) I have used fat arrow function but binding wasn't necessary. – user9347049 Feb 28 '19 at 15:55
0

SOLUTION:

Solution that worked for me was making my App.js parent and LandingPage.js and SearchBar.js pages as child pages.

App.js looked like this:

export default class App extends React.Component{

  render(){
    return(

    <div>
      <Route path="/" exact component={LandingPage} />
      <Route path="/admin" component={Admin}/>
      <Route path="/posts" component={Post} />
      <Route path="/categories" component={Categories} />
      <Route path="/users" component={Users} />
      <Route path="/details" component={Details} />
      <Route path="/profile" component={Profile} />

      <Route path="/weatherapp" component={weatherApp} />
      <Route path="/bar" component={SearchBar}/>
    </div>
  )
 }
}

To make App.js as parent have changed it to look like this:

App.js

export default class App extends React.Component{

  constructor(props){
    super(props)
    this.state = {
        articalName: "Landing page"
    };

}

onSearchSubmit = term => {
  console.log(term);
}


  render(){
    return(

    <div>
      <Route path="/" exact component={LandingPage} />
      <Route path="/admin" component={ () => 
        <Admin 
          title={this.state.articalName}

          />}  
      />
      <Route path="/posts" component={Post} />
      <Route path="/categories" component={Categories} />
      <Route path="/users" component={Users} />
      <Route path="/details" component={Details} />
      <Route path="/profile" component={Profile} />

      <Route path="/weatherapp" component={weatherApp} />
      <Route path="/bar" component={ () => 
        <SearchBar 
          onSubmit={this.onSearchSubmit}

          />}  
         />
    </div>
  )
  }
}

I used routes to send my data from parent to child.

So basically structure of my app looks like this now:

enter image description here

Instead of what it looked like before:

enter image description here

I have stored state in a parent component and pass down the state to child components. This example uses React Router 4. I wanted to use only ReactJs but I guess good solution would be also using Redux.

user9347049
  • 1,927
  • 3
  • 27
  • 66