javascript - React 中的条件渲染在切换时导致重新安装

标签 javascript reactjs modal-dialog redux

我最近一直在与 React 作斗争,试图了解如何正确控制可以由几种不同事物显示的条件渲染元素(例如对话框)。例如,一个项目列表可能每个都有自己的模态内容,但仍然共享相同的模态。我只是在不需要时隐藏模式 (display: none) 并在需要时更改显示。

当每次显示模态时我都需要重新初始化模态,问题就来了。例如,模态包含一系列选项卡,当前选项卡索引存储在模态状态中。关闭并重新打开模式后,我希望当前选项卡索引将重置为零,但事实并非如此;相反,它是隐藏模式之前留下的任何东西。

这样做的一个相当明显的原因是模态框仅在最初呈现时被挂载一次。后续渲染更新不会重新运行安装生命周期方法。显然,解决方案必须包括在需要时重新安装组件(通常是再次显示时)。

我想出了一个可能的例子——当 isDialogShown 改变时,Dialog 应该 卸载和重新挂载。我相当确定 React 能够注意到这一点,并在 isDialogShown 标志发生变化时正确运行生命周期方法。

...
const ParentElement = ({ isElementShown }) => {
  return (
    {!Boolean(isElementShown) 
      ? null
      : <ConditionalElement prop={stuff} />
    }
  );
}
...

CodePen Example - Conditional Rendering

但是,我不确定这是否是最好的方法。我希望有一种方法可以将属性传递给 ConditionalElement 本身,从而使其重新呈现。如果属性是某个值,也许从 render() 函数返回 null?问题是我认为这不会重置 ConditionalElement 本身,但可能会重置所有子项。

const ParentElement = ({ isElementShown }) => {
  return (
      <ConditionalWrapper isShown={true}>
        <ConditionalElement />
      <ConditionalWrapper/>
    }
  );
}

const ConditionalWrapper = ({ children, isShown }) = {
  // Don't render any children if the element should be hidden
  // Also, styles would be applied to hide the wrapper if necessary
  if (!isShown) {
    return null;
  }

  // Render the children if not hidden
  return children;
};

第二种方式似乎没有那么“hacky”,但也有更多的嵌套。无论如何都会推荐它吗?好处是这两种方式都能够“切换”元素(取消/重新安装)和“隐藏”元素(display: none;)(如果应保留本地状态)。这只需要另一个参数(isToggledisShown)。

最佳答案

你的第二种方法是好的 IMO,但是,如果你不喜欢更多嵌套的结果,你可以创建一个高阶组件 (HOC) 来增强组件的行为,增强的组件像原始组件一样工作,只是它知道,比如说,一个“shouldRender”属性,可以在 null 和 null 之间切换底层组件。

const toTogglable = (Elem) => (props) =>
  props.shouldRender ? <Elem {...props}/> : null;

const TogglableA = toTogglable(A);
// Then you can use it like
// <TogglableA shouldRender={true} {...otherProps} />

这种方法的另一个优点是你可以免费获得可组合性,比如如果你想通过属性“shouldHide”概括显示/隐藏的行为,你可以创建另一个 HOC,然后将它们组合起来以增强你的组件,结果总是一个平面组件。

检查 http://codepen.io/anon/pen/MmzpdG一个工作示例,基于您的示例。

关于javascript - React 中的条件渲染在切换时导致重新安装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44088883/

相关文章:

javascript - 在球体上使用多个纹理 [Three.js]

javascript - JSON 树和内存分配

javascript - NodeJS(后端)从POST调用接收数据然后如何在ReactJS(前端)中显示?

javascript - 在react中修改快捷方式如CTRL+F

angular - 在 Angular 2 中打开模态时如何设置 NgbModalOptions

jquery - CSS 3 - 模糊效果叠加模态背景

WinForms模态窗口alt+tab问题

javascript - 根据多个属性在数组中查找唯一对象

mysql - 如何在 Node.js 中使用 Sequelize for MySql 编写 mongoose 的对象 id 引用

javascript - 如何在 AngularJS 中通过 AJAX 添加 ngmodel