使用输入值提交表单后 React Router 重定向

React Router redirect after submitting a form using the input value

Form.js

我希望从此表单中得到的是一个 link,例如 '/search/inputValue/',因此我可以从另一个组件中提取参数。我得到的只是 '/search/' 没有输入值。

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;

我注意到状态在 提交后更新了它的值 较旧的输入值 ,所以问题可能来自这里。

这可以通过删除 Link 标签、防止默认和控制台记录输入值来检查。第一个是空白,第二个是之前输入的值。

我的整个应用程序都已排序,我只需要弄清楚如何从输入提交到 link。

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;

基本上在终于找到一台电脑来帮助你之后,我意识到我的第一个反应是正确的。

您需要:

  • 绑定handleChange方法。您在传递给 React.createClass 的对象中定义的所有方法将自动绑定到组件实例。
  • 每个状态突变都会有一个关联的处理函数。这使得修改或验证用户输入变得简单。这就是为什么我们有 handleChange 函数。
  • 由于在我们的表单元素上设置了 value 属性,因此显示的值将始终为 this.state.value,使 React 状态成为真实的来源。由于 handleChange 在每次击键时运行以更新 React 状态,因此显示的值将随着用户键入而更新..

由于他实际上并没有提交表单,所以这是执行此操作的正确方法。但是,如果您要提交表单,请放弃动态 link 并使用表单操作 属性.

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;

我认为您不应该用 Link 包裹提交按钮。 但是您应该在 onSubmit() 中添加一个 e.preventDefault() 以防止提交表单并防止浏览器 redirection/refresh.

您应该直接在 onSubmit 方法的末尾添加重定向,历史记录 API (https://reacttraining.com/react-router/web/api/history)

我也遇到过同样的问题。 我正在使用 React Router 4 进行一个项目。 目前我发现的是,

  1. 这取决于您如何设置 Routes。

  2. 如果你使用component属性渲染一个组件,比如<Route to="/path" component={Name} />,该组件将有数据(历史,位置和匹配)

  3. 如果是这样,您可以使用输入值使用 history.path 等进行重定向。请参见下面的代码。

  4. 但是,如果你使用render方法如<Route to="/path" render={()=> <Component />} />传递数据给子组件,渲染后的组件什么都没有。

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>
    );
  }
}

在我学习的过程中没有提到它,弄清楚这个小事实真的很痛苦。无论如何,编码愉快!