6

I am currently developing my first reactjs app and am having difficulties navigating from a Search component to a Results component using react-router-dom.

The search component accepts entries from the user, performs a get request with axios and updates its results state.

import axios from 'axios';
import React, {Component} from 'react';
import {Button} from 'react-bootstrap';
import Results from './Results';

class Search extends Component {
  constructor(props) {
    super(props);
    this.state = {
      results: [],
      term: '',
    };

    this.submit = this.submit.bind(this);
    this.changeTerm = this.changeTerm.bind(this);
  }

  changeTerm(event) {
    this.setState({term: event.target.value});
  }

  submit(event) {
    let url = 'http://api.example.com/results?q=' + encodeURI(this.state.term) + '&json=1';
    axios.get(url)
      .then(response => {
        let data = {
          results: response.data,
        };
        this.setState(data);
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <div>
        <form onSubmit={this.submit}>
          <input onChange={this.changeTerm}/>
          <Button type="submit" bsStyle="primary">Find</Button>
        </form>
        <Results data={this.state.results}/>
      </div>
    );
  }
}

export default Search;

The results are currently displayed directly beneath the search component, but I would like to redirect the results to a new page with a different url. Both pages have to be different, because they have completely different structures and styles and must point to different urls.

Is it possible to forward the results from the Search component to the Results Component using react router? I am also open to other solutions which are not based on react router.

Awemo
  • 937
  • 11
  • 23

1 Answers1

11

Have you checked out the Redirect component? Here's a basic idea (without actually testing it) that should get you started. You'll obviously have to add some more code to get it working.

class Search extends Component {
  constructor(props) {
    super(props);
    this.state = {
      results: [],
      term: '',
    };

    this.submit = this.submit.bind(this);
    this.changeTerm = this.changeTerm.bind(this);
  }

  changeTerm(event) {
    this.setState({term: event.target.value});
  }

  submit(event) {
    let url = 'http://api.example.com/results?q=' + encodeURI(this.state.term) + '&json=1';
    axios.get(url)
      .then(response => {
        let data = {
          results: response.data,
        };
        this.setState(data);
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <div>
        <form onSubmit={this.submit}>
          <input onChange={this.changeTerm}/>
          <Button type="submit" bsStyle="primary">Find</Button>
        </form>
        {this.state.results.length > 0 &&
          <Redirect to={{
            pathname: '/results',
            state: { results: this.state.results }
          }}/>
        }
      </div>
    );
  }
}

export default Search;
Tyler McGinnis
  • 30,798
  • 16
  • 69
  • 74
  • Thanks for the answer. I do have a follow up question; can I directly access the state set in the redirect component in the Results component? What I mean: `this.state.results` in the results component, instead of `this.props.location.state.results`. – Awemo Mar 24 '17 at 08:47
  • Nope. That would cause all sorts of issues. – Tyler McGinnis Mar 24 '17 at 22:03
  • 1
    This answer is exactly what I was looking for. Was able to get everything working. However, on the Redirect to my Results page nothing gets passed in, was consoling props and state for my Results page and not getting anything. Also tried different component lifecycle methods as well with nothing be passed in. How can you access what is being passed within that Redirect? – wsfuller Jun 12 '17 at 23:37
  • 3
    Looks like the object was getting passed it was just nested under `location.state` and didn't look there. – wsfuller Jun 13 '17 at 00:08