2
votes

I have a top bar menu with a navbar component with another component that consists on a form with a text input which changes the state of the app component which is father to nav. Nav is outside the router and it has the links to change the routes.

NAV:

import React from 'react';
import {NavLink} from 'react-router-dom';
import SearchInput from './search-input';

var Nav = (props) =>{
	return(

			<nav className="top-bar main-navigation">
				<div className="top-bar-left">
				<ul className="menu">
					<li>
						<NavLink className='logoText' exact to='/'>
							some text
						</NavLink>
					</li>
					<li>
						<SearchInput search={props.executeSearch}/>
					</li>
				</ul>
				</div>
			</nav>
	)
}

export default Nav;

The parent component passes a function to nav and nav to the search-input, this changes the app state. I need to redirect the route to a new one called '/search' when the form is submitted but i can't manage to redirect to search with the Redirect from react-router.

Here are the App component and the SearchBar component:

APP:

import React,{Component} from 'react'
import ReactRouter, {BrowserRouter, Route, Switch, Redirect} from 'react-router-dom';
var Router = BrowserRouter;


import api from '../api/api';

import Nav from './nav';
import GameView from './main-view';
import Home from'./home';
import Search from './search';



class App extends Component {
  constructor(props){
    super(props);
    this.state={
      searchResult:null,
      redirect:false
    }
    this.search= this.search.bind(this);
  }

  search(term,type){
    api.searchElements(term,type)
      .then((searchResult)=>{
        console.log(searchResult);
        this.setState({searchResult});
      })
      .catch((e)=>{
        console.log(e);
      })
  }

  render() {


    return (
      <Router>
        <div>
          <Nav executeSearch={this.search}/>
          <Switch>

            <Route exact path='/' component={Home}/>
            <Route path='/main' component={MainView}/>
            <Route path='/search' component={Search}/>

          </Switch>
        </div>
      </Router>
    )
  }
  componentDidMount() {
    document.title = 'My page';
  }
}

module.exports = App;

import React, {Component} from 'react';
import ReactRouter, {Redirect} from 'react-router-dom';

import api from '../api/api';

export default class SearchInput extends Component{
	constructor(props){
		super(props);

		this.state = {
			term: null
		}
	}
	onInputTerm(term){
		this.setState({term});
	}
	onSumbitTerm(term){
		this.props.search(term,'games');
	}
	render(){
		return(
				<div className='search-bar' >
					<form
						onSubmit={(e)=>{
								e.preventDefault();
								this.onSumbitTerm(e.target.searchValue.value);
							}}
					>
						<input 
							name='searchValue'
							type='text'
							onChange={(e)=>{this.onInputTerm(e.target.value)}} 
						/>
					</form>
				</div>
			);
	}
}

I'm pretty new to React, sorry if I'm asking something really dumb. Thanks in advance.

1

1 Answers

1
votes

Well I didn't understand your exact business problem. But it seems like you need to do some programmatic navigation upon the form submission. What you need to do here is call the action creator by passing a callback function which is responsible for programmatic navigation. Then inside the action creator once the promise is resolved, merely call the callback function to do the navigation. An example is given below.

Here's the form submission function.

  onSubmit(values) {
    this.props.createPost(values, () => {
      this.props.history.push('/');
    });
  }

Here's the action creator which invokes the callback function that gets passed into it, when the promise is resolved to navigate into a different url.

export function createPost(values, callback) {
  const request = axios.post(`${ROOT_URL}/posts`, values)
    .then(() => callback());

  return {
    type: CREATE_POST,
    payload: request
  };
}

Hope this helps. Happy coding !