React Router redirect after submitting a form using the input value

10,140

Basically after finally getting to a computer to help you, I realized one of my first responses was correct.

You needed to:

  • Bind the handleChange method. All methods you define in an object passed to React.createClass will be automatically bound to the component instance.
  • Every state mutation will have an associated handler function. This makes it straightforward to modify or validate user input. That is why we have the handleChange function.
  • Since the value attribute is set on our form element, the displayed value will always be this.state.value, making the React state the source of truth. Since handleChange runs on every keystroke to update the React state, the displayed value will update as the user types..

Since he is not submitting a form actually, this is the correct way to do this. However, if you were submitting form, ditch the dynamic link and use the form action property.

import React from 'react';
import { Link } from 'react-router-dom';

class App extends React.Component {
 /** Left some things in here commented out, 
     incase you start doing form submissions. Instead of a dynamic link.
  **/
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);

    /**  If you start submitting forms
    this.handleSubmit = this.handleSubmit.bind(this);  
    **/
  }

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

  /** If you start submitting forms, add onSubmit={this.onSubmit} to form action
  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  } 
  **/

  render() {
    return (
    <div>
       <form className="form-inline">
                <div className="form-group">
                    <input type="text" value={this.state.value} onChange={this.handleChange} className="form-control" name="keyword" placeholder="Image keyword" />

                    <Link to={`/search/${this.state.value}`}>
                        <button className="btn btn-primary">Search</button>
                    </Link>
                </div>
            </form>
      </div>
    );
  }
}

export default App;
Share:
10,140

Related videos on Youtube

Vlad Bibire
Author by

Vlad Bibire

Updated on June 04, 2022

Comments

  • Vlad Bibire
    Vlad Bibire almost 2 years

    Form.js

    What I wish to get out of this form is a link like '/search/inputValue/' so from another component I can extract the parameter. What I get instead is just '/search/' without the input value.

    import React from 'react';
    import { Link } from 'react-router-dom';
    
    class Form extends React.Component {
        state = {
            searched: ''
        }
    
        onSubmit = (e) => {
            const keyword = e.target.elements.keyword.value;
            this.setState({ searched: keyword });
        }
    
        render(){
            return (
                <form className="form-inline" onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <input type="text" className="form-control" name="keyword" placeholder="Image keyword" />
    
                        <Link to={ `/search/${this.state.searched}`}>
                            <button className="btn btn-primary">Search</button>
                        </Link>
                    </div>
                </form>       
            );
        }
    };
    
    export default Form;
    

    I have noticed that the state updates its value after a second submit with the older input value, so the problem might be from here.

    This can be checked by removing the Link tag, preventDefault and console log the input value. The first one is blank and the second one is with the previous input value.

    My whole app is sorted, I just need to figure how to submit to a link from an input.

    Router.js

    import React from 'react';
    import { BrowserRouter, Route, Switch } from 'react-router-dom';
    
    import App from '../App';
    import SearchPage from './SearchPage';
    
    const Router = () => (
        <BrowserRouter>
            <Switch>
                <Route path="/" component={App} exact />
                <Route path="/search/:keyword" component={SearchPage} />
            </Switch>
        </BrowserRouter>
    );
    
    export default Router;
    
  • Vlad Bibire
    Vlad Bibire over 5 years
    I understand your point of view, however, you have no input in your form. What I'd like to achieve is something like 'this.props.history.push('/search/' + inputValue)'. I've also update my request with the Router.js file so it will be more explicit
  • ABC
    ABC over 5 years
    I edited it, I am trying to help you without a computer handy. I think I got the idea. Then you would just add the input, and replace the query parameter to the url endpoint. I figured you understand the part.
  • Vlad Bibire
    Vlad Bibire over 5 years
    Please re-read the request one more time so it will be more clear. Your form must have an <input type=text /> and the value entered there should appear in a link like '/search/inputValue'.. hope it's easier now
  • ABC
    ABC over 5 years
    I edited it again. You bind the value up top in my example, and while onChange you are constantly updating the state. Then you had the right idea in the link to have it read the state for the current searched string. I understand what your trying to do now, tell me if it works.
  • ABC
    ABC over 5 years
    We had tried the history method in one of my original responses, it seems he wants a link that is dynamically changes its href. And when he types in form, first type is null. Second is valid from state.
  • Vlad Bibire
    Vlad Bibire over 5 years
    Damn, I appreciate the effort you put into this.. but the problem is just with that stat for showing the first value to be an empty string and then the second one being the one I need.
  • Vlad Bibire
    Vlad Bibire over 5 years
    Link being from react-router it will not cause a refresh, just a redirect to another component. With or without preventDefault, is the same result in this situation. I will try with history and come back with an answer
  • Vlad Bibire
    Vlad Bibire over 5 years
    Yes, as @Raymond said. A dynamic link created by a user input. Basically, it's a search form and after the user enters his request, for example 'desk', the link should be '/search/desk' but first state value is null, and the second one is valid
  • Bastien
    Bastien over 5 years
    The problem with you solution is that you ask for react-router to redirect to a link. but at the same time your form is submitted and so your browser refesh itself
  • Vlad Bibire
    Vlad Bibire over 5 years
    You are a God! Thank you so much for this. Works exactly as I wanted
  • ABC
    ABC over 5 years
    No problem, I know how it is. Idk if there is a way for me to follow you or you let me know if you have any questions but I'll keep an eye out. I am editing my post to explain exactly what I did, and how there is a better way to do it. Good luck, and no problem.
  • Vlad Bibire
    Vlad Bibire over 5 years
    Sure it is, @vladbbr on Twitter. I will post there a final GIF with the app working and also making an Youtube video about this so, trust me, you did a lot more good than you expected. Many thanks again
  • amir hosein ahmadi
    amir hosein ahmadi over 5 years
    @Raymond sorry i didn't saw your answer , i removed mine :)