【问题标题】:How to organize actions that don't modify state?如何组织不修改状态的动作?
【发布时间】:2017-10-29 06:35:50
【问题描述】:

假设我有一个这样的反应组件:

class App extends Component {
  print = () => {
    const { url } = this.props
    const frame = document.createElement('iframe')

    frame.addEventListener('load', () => {
      const win = frame.contentWindow

      win.focus()
      win.print()
      win.addEventListener('focus', () => document.body.removeChild(frame))
    })

    Object.assign(frame.style, {
      visibility: 'hidden',
      position: 'fixed',
      right: 0,
      bottom: 0
    })

    frame.src = url

    document.body.appendChild(frame)
  }

}

基本上,单击按钮会为用户调用浏览器中的打印功能。在这种情况下,我是否仍然将其变成像 DO_PRINT 这样的 redux 操作,它实际上对我的 redux 状态没有任何作用,还是我只是不理会它?

【问题讨论】:

    标签: javascript reactjs redux action


    【解决方案1】:

    对于您的特定示例,我会避免创建 Redux 操作,因为如果 DO_PRINT 仅调用 window.print(),则无需更新任何状态。

    事实上,假设您正在创建一个“打印按钮”组件,我会将其重新定义为一个哑组件。 (见differences between presentationl and container components。)

    import React from ‘react’;
    
    const PrintButton = () => {
      const onClick = () => {
        window.print();
      };
    
      return <button onClick={onClick}>Click Me</button>
    };
    
    export default PrintButton;
    

    仅供参考,上面的代码可能不是为无状态组件声明事件处理程序的最有效方式,因为每次渲染组件时都会调用该函数。可能有更好(更有效)的方法(described in another SO question),但这超出了这个问题。

    【讨论】:

    • 您好,感谢您的回答!我原来的帖子有点含糊,所以我用打印功能的实际代码更新了我的帖子。就我而言,我实际上需要为我的打印创建一个隐藏的iframe,以便不打开新窗口。你仍然认为我不应该把它变成一个 redux 动作吗?
    • 不客气!我看到附加代码仍然不涉及任何数据/状态,所以答案应该仍然有效。话虽如此,我会避免直接在 React 中操作 DOM,而是使用组件。
    • 嗯,我明白了。所以我在这里做的是制作一个临时 iframe,并从中调用 print,然后将其删除。我认为我无法使用组件来做到这一点,除非您的意思是只保持一个 iframe 处于活动状态并可选择根据我是否单击打印来渲染它?
    • 可能有点反模式,但你应该能够;我在想一些类似于this codepen 的东西。
    猜你喜欢
    • 1970-01-01
    • 2022-08-16
    • 2015-05-16
    • 2021-01-30
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多