React + Redux:以编程方式更改输入焦点

时间:2017-10-08 17:03:45

标签: javascript reactjs redux react-redux

我有一个带有'是/否'问题界面的反应应用程序。我正在使用redux来管理状态。

该应用程序提供了一系列动态添加的输入字段。

当用'y''n'按键回答问题时,我希望系列中的下一个输入能够自动获得焦点 - 启用快速数据-条目。事实证明这很难!

我的redux商店包含当前问题的索引 - 我希望将其转换为关注该输入。

/*Input Component*/
const quizQs = ({

    questionArray = ["Q1", "Q2", "Q3", "Q4"]
    currentQIndex, //From Store
    changeQIndex,  //Action

}) => {


    const _handleKeyDown = (e) => {
        if(e.key == 'y' || e.key == 'n'){
          //Dispatches Action that increases current currentQIndex'
        }
    }
    //_handleFocus()... for updating currentQIndex if an input is focused by the user


    return (
        {questionArray.map((q, index) => {

            return(
                <input
                  key={index}
                  onKeyDown={_handleKeyDown}
                  onFocus={_handleFocus}
                  type="text"
                  placeholder={q}
                  />
            )
        })}
        )
}


/*Main Component -- Connected to Store*/
class myQuiz extends React.Component {

constructor(props){
    super(props);
}


render(){
    return(
        <div>

            <quizQs
                currentQIndex = {this.props.currentQIndex} 
                changeQIndex = {this.props.changeQIndex}
                />
        </div>

    )}
}

我已尝试在autoFocus = true组件中设置'currentQIndex',如果商店的'quizQs'与该特定问题的索引匹配。当页面首次渲染时,此方法可以聚焦指定的字段,但是当商店的'currentQIndex'发生更改时,焦点不会更改。

当我搜索到答案时,React 'refs' +使用回调似乎是要走的路,(https://reactjs.org/docs/refs-and-the-dom.html#the-ref-callback-attribute),但我无法弄清楚如何设置这样的{ {1}}回调,响应Redux商店中的更改。

此外,为了使用'focus',必须将组件设置为类,而不是箭头函数。 AFAIK,在一个文件中包含多个类并不是一个好习惯,将这么多不同的组件连接到redux存储似乎不合适。

我很感激帮助。

1 个答案:

答案 0 :(得分:2)

以下是您尝试实现的简单示例:https://codesandbox.io/s/z64qw3nkzx

我对它进行了简化,但关键在那里。

由于.focus()是DOM元素的本机方法,因此您需要一种跟踪这些输入元素的方法。对于React中的那个,有ref道具。它接受一个带有一个参数的函数,该参数是组件的实际DOM元素。

你会看到我将所有DOM引用放入一个数组中:

<input
  ref={el => this.questionInputElements[index] = el}
  key={index}
  // all other props
/>

并在键盘上*找到数组中的下一个元素并将其聚焦:

const nextInput = this.questionInputElements[index + 1];

if (nextInput) {
  nextInput.focus();
}

*它需要按键(而不是按键),因为它会聚焦下一个字段并在下一个输入中打印y / n。试试它是为了好玩:)