繁体   English   中英

来自门户的 React-Router 重定向而不是重定向

[英]React-Router Redirect from a portal not redirecting

我正在开发用于 React 实践的 Twitch 克隆应用程序,并且正在为用户想要删除视频流时创建模态弹出窗口。 基本上他们有一个流列表,他们点击其中一个流上的删除按钮,然后使用ReactDOM.createPortal打开一个模式

这是删除按钮

import React from "react";

import Modal from "../Modal";

const StreamDelete = () => {

  return (
    <>
      <Modal />
    </>
  );
};

export default StreamDelete;

这是模态的代码

import React from "react";
import ReactDOM from "react-dom";
import { Redirect } from "react-router-dom";

const Modal = () => {

  
  return ReactDOM.createPortal(
    <div
      className="ui dimmer modals visible active"
      onClick={ () => {
        return <Redirect to="/" />;
      } }
    >
      <div className="ui standard modal visible active">
        <div className="header">Delete Stream</div>
        <div className="content">
          Are you sure you want to delete this stream?
        </div>
        <div className="actions">
          <button className="ui primary button">Delete</button>
          <button className="ui button">Cancel</button>
        </div>
      </div>
    </div>,
    document.querySelector("#modal")
  );
};

export default Modal;

模态的外观

此模式只能在 React-Router 路由/streams/:id/delete上查看

我的预期行为是,当我单击深色背景时,我的onClick函数应该返回<Redirect to="/">因此应该关闭模态窗口,因为它没有在该路径中呈现。

我得到的行为是点击深色背景不会重定向,尽管我也没有收到任何错误。

有关此项目的 GIT 存储库的其他上下文,请访问Glitch Client

到目前为止,我在Ncoughlin: Tag Twitch Clone上有关于这个项目所有部分的大量笔记

由于StreamDelete是由Route组件直接渲染的

<Route path="/streams/:id/delete" exact component={StreamDelete} />

解决方案

它通过路由道具,因此可以访问history道具。 您可以在StreamDelete使用它并将回调传递给模态以执行您想要的操作。

const StreamDelete = ({ history }) => {
  const doRedirect = () => history.replace("/");
  return (
    <>
      <Modal onDelete={doRedirect} />
    </>
  );
};

模态

const Modal = ({ onDelete }) => {
  return ReactDOM.createPortal(
    <div
      className="ui dimmer modals visible active"
      onClick={onDelete}
    >
      <div className="ui standard modal visible active">
        <div className="header">Delete Stream</div>
        <div className="content">
          Are you sure you want to delete this stream?
        </div>
        <div className="actions">
          <button className="ui primary button">Delete</button>
          <button className="ui button">Cancel</button>
        </div>
      </div>
    </div>,
    document.querySelector("#modal")
  );
};

选择

如果您出于某种原因想避免使用history道具,则使用声明式实现。

在模态中使用一些“重定向”状态有条件地呈现一个Redirect

const Modal = () => {
  const [redirect, setRedirect] = useState(false);

  if (redirect) {
    return <Redirect to="/" />;
  }
  
  return ReactDOM.createPortal(
    <div
      className="ui dimmer modals visible active"
      onClick={() => setRedirect(true)}
    >
      <div className="ui standard modal visible active">
        <div className="header">Delete Stream</div>
        <div className="content">
          Are you sure you want to delete this stream?
        </div>
        <div className="actions">
          <button className="ui primary button">Delete</button>
          <button className="ui button">Cancel</button>
        </div>
      </div>
    </div>,
    document.querySelector("#modal")
  );
};

建议的替代方案

不要将应用行为与展示(即模态)组件结合起来。 根据模态的某些“确认”, StreamDelete地在StreamDelete呈现Redirect

const StreamDelete = () => {
  const [confirm, setConfirm] = useState(false);
  
  return confirm ? (
    <Redirect to="/" />
  ) : (
    <Modal onConfirm={() => setConfirm(true)} />
  );
};

按照上面链接的文章中的示例,我还能够使其发挥作用。 转换为组件,创建状态,使用单击处理程序触发辅助函数,该函数设置状态以有条件地呈现重定向。

import React from "react";
import ReactDOM from "react-dom";
import { Redirect } from "react-router-dom";

class Modal extends React.Component {
  state = {
    toDashboard: false,
  }

  handleClick = () => {
    this.setState(() => ({
      toDashboard: true
    }))
  }


  render() {
    if (this.state.toDashboard === true) {
      return <Redirect to='/' />
    }

    return ReactDOM.createPortal(
      
      <div
        className="ui dimmer modals visible active"
        onClick={ this.handleClick }
      >
        <div className="ui standard modal visible active">
          <div className="header">Delete Stream</div>
          <div className="content">
            Are you sure you want to delete this stream?
          </div>
          <div className="actions">
            <button className="ui primary button">Delete</button>
            <button className="ui button">Cancel</button>
          </div>
        </div>
      </div>,
      document.querySelector("#modal")
    );
  }
  
};

export default Modal;

这篇文章ui.dev 中解释了这种技术:程序化导航

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM