React Router redirect after submitting a form using the input value
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;
Related videos on Youtube
Vlad Bibire
Updated on June 04, 2022Comments
-
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 over 5 yearsI 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 over 5 yearsI 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 over 5 yearsPlease 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 over 5 yearsI 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 over 5 yearsWe 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 over 5 yearsDamn, 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 over 5 yearsLink 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 over 5 yearsYes, 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 over 5 yearsThe 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 over 5 yearsYou are a God! Thank you so much for this. Works exactly as I wanted
-
ABC over 5 yearsNo 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 over 5 yearsSure 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 over 5 years@Raymond sorry i didn't saw your answer , i removed mine :)