首页 > 解决方案 > 当模态在反应中打开时,后台组件会卸载吗?如果没有,如何使用 redux 维护/存储模态和反应组件的状态?

问题描述

演示(不工作,但文件结构) https://codesandbox.io/s/material-demo-bsr06

  1. 当我单击此 URL 中的某些内容时,我需要打开一个 Modal dashboard/someMails,它应该以dashboard/someMails/:id.

  2. 我想维护 someMmails 页面的其中一封电子邮件的状态以及该特定电子邮件的模式,反之亦然

  3. 在 React 路由器中,我切换

     <Switch>
       <Route path="dashboard/someMails" component={EmailsHome} />
       <Route path="dashboard/someMails/:id" component={EmailModal} />
     </Switch>` 
  1. 由于我需要维护状态,因此将状态存储在 reducer(redux) 中。

  2. 但何时存储是个问题。

    a) 我可以在 componentUnMounts 时存储吗?b) 模态打开时组件会卸载吗?c)如果组件不会卸载,我应该继续触发 reducer 方法来存储每次状态更改EmailsHome还是EmailModal

标签: reactjsreduxreact-routermodal-dialogmaterial-ui

解决方案


当您导航到模态路线时,组件将卸载。话虽如此,componentWillUnmount()除了清理方法之外,您应该避免在内部执行逻辑。

看起来您想stateredux用户单击电子邮件时更新一些内容,从而使他们导航到不同的位置route并打开模式。

如果是这种情况,您应该在将它们发送到另一个页面的onClick()处理程序中触发此操作。Link

我创建了一个关于如何实现此功能的基本模板:https ://codesandbox.io/s/material-demo-wpisp

完整的部分在这里:

电子邮件.js

import React, { useState } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { updateEmail } from "./emailActions";

const Email = props => {
  const [checked, setChecked] = useState(props.read);
  return (
    <div>
      <button
        style={{ background: "transparent", border: "none" }}
        onClick={() => props.updateEmail(props.id, checked)}
      >
        <Link to={`/dashboard/someMails/${props.id}`}>{props.message}</Link>
      </button>
      <button onClick={() => setChecked(!checked)}>Mark As Read</button>
      <p>{checked ? "Read" : "Unread"}</p>
    </div>
  );
};

const mapDispatchToProps = dispatch => {
  return {
    updateEmail: (id, value) => {
      dispatch(updateEmail(id, value));
    }
  };
};

export default connect(
  null,
  mapDispatchToProps
)(Email);
  1. 当您单击“标记为已读”时,将切换电子邮件组件的“已检查”状态。
  2. 后续点击链接,它会调用我们的action-creator,它会传入消息的id和state-value(true或false)。
  3. Redux 保存着我们的消息数组,用匹配的 id 更新消息,并获取我们在组件中配置的状态值。将“读取”值设置为(真或假)。

EmailModal.js

import React, { useEffect } from "react";
import { connect } from "react-redux";
import { getEmail } from "/emailActions";
import { Link } from "react-router-dom";

const EmailModal = ({ emails, getEmail, match }) => {
  useEffect(() => {
    const id = match.params.id;
    getEmail(id);
  }, []);

  return (
    <div>
      <Link to="/dashboard/someMails">Back to emails</Link>
      <h4>Message: {emails.currentEmail.message}</h4>
      <h4>Read:{"" + emails.currentEmail.read}</h4>
    </div>
  );
};

const mapStateToProps = state => {
  return {
    emails: state.emails
  };
};

const mapDispatchToProps = dispatch => {
  return {
    getEmail: id => {
      dispatch(getEmail(id));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(EmailModal);
  1. 组件挂载后,我们调用 action-creator 来在 Redux 中查找与我们 url 中的 id 相同的电子邮件。
  2. 我们显示该电子邮件,现在取决于您是否更改了上一页中电子邮件的状态(已读或未读),它将获取更新后的值并将其显示在模式中。

总而言之,是的,您可以在 React 正在导航到另一个 Route 的过程中执行 redux-logic。在此,我们将一些组件状态值传递给动作创建器,它更新了 redux-state,当我们最终导航到模态组件时,它得到了更新的值。


推荐阅读