【问题标题】:How to handle focus using declarative/functional style libraries like Redux and ReactJS?如何使用 Redux 和 ReactJS 等声明式/函数式库来处理焦点?
【发布时间】:2016-04-22 20:37:51
【问题描述】:

在查看其他开发人员在使用 Redux 时处理输入焦点的方式时,我发现了一些针对 ReactJS components such as this 的一般指导。然而,我担心的是 focus() 函数是必不可少的,我可以看到在多个组件争夺焦点的情况下可能出现的奇怪行为。是否有处理焦点的 redux 方式?有没有人处理使用 reduxreact 务实地设置焦点,如果是,你使用什么技术?

相关:

【问题讨论】:

  • Redux 和 DOM 节点/DOM 函数,实际上彼此没有任何关系……不知道您期望 Redux 如何参与。为什么多个组件会争夺焦点,你想避免什么样的奇怪行为?
  • 正如 azium 所说,redux 只是一种管理和存储应用程序状态的方式。所以也许你应该重新提出你的问题——你是在问如何管理多个设置了 focus() 的组件,当它们一起呈现在页面上时,你想决定哪个组件真正获得焦点?我想这将完全取决于您的应用程序!我猜它默认是最后渲染的那个。还要考虑autofocus 属性。
  • Dominic,你很好地描述了我的担忧。多个组件打算设置焦点,但只有一个会获胜。最后,渲染视图将与声明性表示不同步,部分原因是调用 focus() 时不再是声明性的,还因为获得焦点的行为会导致副作用。
  • 我尝试了自动对焦,但由于某种原因它不起作用,但我还没有机会深入研究原因。

标签: reactjs focus flux redux


【解决方案1】:

我的方法是使用ref 回调,这是一种元素的onRenderComplete。在那个回调中,我可以集中注意力(如果需要,有条件地)并获得未来关注的参考。

如果输入在动作运行后有条件地呈现,则该 ref 回调应触发焦点,因为在调用该动作后该 ref 还不存在,但仅在渲染完成后才存在。处理componentDidUpdate 之类的focus 似乎是一团糟。

// Composer.jsx -- contains an input that will need to be focused somewhere else

class Composer extends Component {
  render() {
    return <input type="text" ref="input" />
  }

  // exposed as a public method
  focus() {
    this.refs.input.focus()
  }
}

// App.jsx

@connect(
  state => ({ isComposing: state.isComposing }),
  ...
)
class App extends Component {
  render() {
    const { isComposing } = this.props // or props, doesn't matter
    return (
      <div>
        <button onClick={::this._onCompose}>Compose</button>
        {isComposing ? <Composer ref={c => {
          this._composer = c
          this._composer && this._composer.focus() // issue initial focus
        }} /> : null}
      </div>
    )
  }

  _onCompose() {
    this.props.startComposing() // fire an action that changes state.isComposing

    // the first time the action dispatches, this._composer is still null, so the ref takes care of the focus. After the render, the ref remains so it can be accessed:

    this._composer && this._composer.focus() // focus if ref already exists
  }
}

为什么不用autoFocusisFocued 道具?

由于HTMLInputElementvalue 作为道具,但focus() 作为方法——而不是isFocused 道具——我会继续使用方法来处理它。 isFocused 可以得到一个值,但是如果用户从输入中模糊,该值会发生什么?会不同步。此外,正如 cmets 中所述,autoFocus 可能与多个组件发生冲突

那么如何在 props 和 methods 之间做出选择呢?

在大多数情况下,道具就是答案。方法只能用于“一劳永逸”的事情,例如scrollToBottom 在有新消息时的聊天中,scrollIntoView 等。这些是商店不关心的一次性行为,用户可以通过交互进行更改,因此布尔属性不适合。对于所有其他事情,我会选择道具。

这是一个 jsbin:

http://jsbin.com/waholo/edit?html,js,output

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2017-12-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    相关资源
    最近更新 更多