最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Router redirect after submitting a form using the input value - Stack Overflow

programmeradmin2浏览0评论

Form.js

What I wish to get out of this form is a link like '/search/inputValue/' so from another ponent 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="/" ponent={App} exact />
            <Route path="/search/:keyword" ponent={SearchPage} />
        </Switch>
    </BrowserRouter>
);

export default Router;

Form.js

What I wish to get out of this form is a link like '/search/inputValue/' so from another ponent 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="/" ponent={App} exact />
            <Route path="/search/:keyword" ponent={SearchPage} />
        </Switch>
    </BrowserRouter>
);

export default Router;
Share Improve this question edited Oct 2, 2018 at 14:08 Vlad Bibire asked Oct 2, 2018 at 13:56 Vlad BibireVlad Bibire 251 gold badge1 silver badge5 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

Basically after finally getting to a puter 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 ponent 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 mented 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;

I think you should not wrap the submit button with a Link. But you should add a e.preventDefault() in your onSubmit() to prevent form to be submitted and prevent the browser to redirection/refresh.

You should add the redirection directly at the end of your onSubmit method with the history API (https://reacttraining./react-router/web/api/history)

I've struggled with the same issue. I am on a project with React Router 4. What I found so far is,

  1. It depends on how you set up your Routes.

  2. If you use ponent attribute to render a ponent, such as <Route to="/path" ponent={Name} />, the ponent will have data (history, location and match)

  3. If so, you can use input value to redirect using history.path etc. See the code below.

  4. However, if you use render method such as <Route to="/path" render={()=> <Component />} /> to pass data to a child ponent, the rendered ponent have nothing.

class Home extends Component {
  handleSubmit = e => {
    e.preventDefault();
    let teacherName = this.name.value;
    let teacherTopic = this.topic.value;
    let path = `teachers/${teacherTopic}/${teacherName}`;
    // this is the part !!!
    this.props.history.push(path);
  };

  render() {
    return (
      <div className="main-content home">
        <h2>Front End Course Directory</h2>
        <p>
          This fun directory is a project for the <em>React Router Basics</em> course on Treehouse.
        </p>
        <p>
          Learn front end web development and much more! This simple directory app offers a preview
          of our course library. Choose from many hours of content, from HTML to CSS to JavaScript.
          Learn to code and get the skills you need to launch a new career in front end web
          development.
        </p>
        <p>
          We have thousands of videos created by expert teachers on web design and front end
          development. Our library is continually refreshed with the latest on web technology so you
          will never fall behind.
        </p>
        <hr />
        <h3>Featured Teachers</h3>
        <form onSubmit={this.handleSubmit}>
          <input type="text" placeholder="Name" ref={input => (this.name = input)} />
          <input type="text" placeholder="Topic" ref={input => (this.topic = input)} />
          <button type="submit">Go!</button>
        </form>
      </div>
    );
  }
}

It was mentioned nowhere while I am learning, was really pain in the ass to figure out just this small fact. Anyway, happy coding!

发布评论

评论列表(0)

  1. 暂无评论