【问题标题】:Redirect with React Functional Components使用 React 功能组件重定向
【发布时间】:2020-03-25 13:15:26
【问题描述】:

我需要帮助,我正在编写此表单,提交后,“已发布”的状态从 false 变为 true,我希望“return Redirect to="/landing" ;”但是,将我重定向到登录页面,我认为这不是因为该行在初始渲染后没有重新运行。我希望更改“已发布”的状态会导致重新渲染。我听说过使用历史推送并尝试将其调整为我的代码,但我失败了。我不知道如何用“withRouter”包装我的组件,因为我已经用“connect”包装了它。我怎样才能做到这一点?我已经阅读了很多关于此的帖子,但我不知道如何使其适应我的代码。任何帮助表示赞赏。

import React, { useState } from "react";
import Navbar from "./Navbar";
import { connect, useDispatch } from "react-redux";
import { Redirect } from "react-router-dom";
import { createProject } from "../actions/projectAction";
import PropTypes from "prop-types";
import { push } from "connected-react-router";

const EditProject = ({ posted, createProject }) => {
  const dispatch = useDispatch();
  const [formData, setFormData] = useState({
    projectTitle: "",
    projectDescription: "",
    deliveryDate: ""
  });

  const { projectTitle, projectDescription, deliveryDate } = formData;

  const onChange = e => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  const onSubmit = async e => {
    e.preventDefault();
    createProject({ projectTitle, projectDescription, deliveryDate });
    dispatch(push("/login"));
  };

  if (posted) {
    return <Redirect to="/landing" />;
  }

  return (
    <div>
      <Navbar />
      <div className="container">
        <form onSubmit={e => onSubmit(e)}>
          <h4>Project Title</h4>
          <input
            name="projectTitle"
            value={projectTitle}
            className="form-control"
            placeholder="Your project title"
            onChange={e => onChange(e)}
          />
          <h4>Delivery Date</h4>
          <input
            type="date"
            className="form-control"
            name="deliveryDate"
            value={deliveryDate}
            onChange={e => onChange(e)}
          />
          <h4>Description</h4>
          <textarea
            name="projectDescription"
            value={projectDescription}
            className="form-control"
            rows="10"
            onChange={e => onChange(e)}
          ></textarea>
          <input type="submit" className="btn btn-primary" value="Create" />
          <a href="/projects" className="btn btn-danger">
            Cancel
          </a>
        </form>
      </div>
    </div>
  );
};

EditProject.propTypes = {
  createProject: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
  posted: state.posted
});

export default connect(mapStateToProps, { createProject })(EditProject);

【问题讨论】:

  • 这段代码应该可以工作。您检查posted 的值是否符合预期? (例如,console.log('posted', posted) 就在if 的上方)如果是这样,问题将在于路由器的初始化方式(例如,&lt;Route path="/lnding"&gt; 中的拼写错误)。如果不是,则问题很可能出在 redux 中(例如,reducer 未正确设置 state.posted)。

标签: javascript reactjs forms react-redux react-router


【解决方案1】:

我认为你必须定义你的路线。从我的以下代码中,您可以对路由有所了解。

App.js中,基本上我定义了路由,并且我创建了另外两个功能组件LandingEditProject来模拟你的想法。此外,我已将 Link 用于导航目的

App.js

import React, { Component } from "react";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
import EditProject from "./editProject";
import Landing from "./landing";

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div id="container">
          <div>
            <Link to="/">Landing Page</Link>
            <Link to="/editproject">Edit Project</Link>
          </div>
          <Switch>
            <Route path="/editproject" component={EditProject} />
            <Route exact path="/" component={Landing} />
          </Switch>
        </div>
      </BrowserRouter>
    );
  }
}

export default App;

Landing功能组件

import React from "react";

const Landing = () => {
  return <h1>Landing Page</h1>;
};

export default Landing;

EditProject功能组件

import React from "react";

const EditProject = props => {
  function handleSubmit(e) {
    e.preventDefault();
    console.log("submitted");
    //do your task here before redirect
    //...
    props.history.push("/");
  }

  return (
    <div>
      <h1>Edit Project</h1>
      <form onSubmit={handleSubmit}>
        <button>Submit</button>
      </form>
    </div>
  );
};

export default EditProject;

希望对你有所帮助。

【讨论】:

  • 谢谢,我做了和你类似的实现,现在我可以在提交表单后重定向!
  • 好的,如果我的回答对您有帮助,或者如果您认为此答案也可以帮助其他人,请勾选并投票以向其他人传达此答案
  • 嗨@tareqaziz 如何在路由器上获取功能组件状态值
【解决方案2】:

我想在您的代码中解决两件事。

如果EditProject 组件直接指向Route,那么您可以访问推送。

const EditProject = ({ { posted, createProject, history: { push } }) => {
    push() // your access to push
}

其次,在您的连接中,我不支持您的连接想法。可能是提交功能没有运行。

您可以执行以下操作来有所作为。

export default connect(mapStateToProps, { handleNewProject, createProject })(EditProject);

现在,重写EditProject 组件将是

import React, { useState, useEffect } from "react";

const EditProject = ({ { posted, handleNewProject, history: { push } }) => {
    push() // your access to push
    // useEffect React component life cycle Hook
    useEffect(() => () => push('/landing'), [posted]);

}

请注意,我使用 React Hook 就像您使用 React class component life circle 的方式一样。

【讨论】:

    【解决方案3】:

    说,在注销提交按钮上,我想转到用户/登录页面:

    export default function MyComponent(props) {    
        // ...
    
        const handleSubmit = async (event) => {
            props.history.push('/user/login');
        }
    }
    

    注意:如果组件参数中不存在props,您可以添加它。


    react.js 中的一些其他非标准方式(但常用于大型项目)

    以下其中一项将起作用:

    let url = '/user/login'
    
    props.history.push(url);
    
    window.location = url;
    window.location.href = url;
    window.location.replace(url);
    
    window.open(url)
    window.open(url, "_self")
    window.open(url, '_blank');
    window.open(url, 'newWindow');
    window.open(url, 'newwin');
    
    window.location.reload(true);
    

    【讨论】:

    • 应该是这个吗? props 对我来说是一个空对象
    • 当然,请参阅上面的答案,您可以添加props 或使用window. 方法之一,请参阅上面的更新答案。
    • 对我来说,它通过导入 import { useHistory } from 'react-router-dom' 起作用,然后我声明 const history = useHistory(); 然后我可以在 jsx history.push('/some-page'); 中使用它
    • @FedericoCapaldo 很酷,很高兴知道有类似的工作。
    猜你喜欢
    • 2020-04-07
    • 1970-01-01
    • 2016-02-21
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    相关资源
    最近更新 更多