繁体   English   中英

ReactJS类组件使用contenteditable元素渲染array.map

[英]ReactJS class component render array.map using contenteditable elements

我遇到了一个有趣的问题,我无法调试。

目标

在类组件的渲染函数内部,使用this.state.items.map((item, index) => {})state遍历对象数组,并返回contentEditable段落元素。

在每个contentEditable段落元素上,侦听onKeyUp事件。 如果从所使用的密钥的存在e.which是输入(13)项中,添加一个新的项,以this.state.items使用已键入的元素的索引,以便使用该索引之后插入一个新元素splice

看到预期的结果了吗?

不会。新添加的项目在呈现时会放在循环的末尾。

示例情况和重现步骤:

  1. 在第一个P元素中输入“ test1”
  2. 按下回车键(创建了一个新的P元素并将其聚焦)
  3. 在第二个新创建的P元素中输入“ test2”
  4. 通过Shift + Tab或单击重新聚焦于第一个P元素
  5. 点击进入
  6. 查看观察到的结果:创建并聚焦了一个新的P元素,但它位于列表的末尾,而不是预期的位置,它位于“ test1”和“ test2” P元素之间

这是我到目前为止的代码:

class MyComponent extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            items: [this.paragraphTemplate()]
        }
    }

    render() {
        return (
            <section>
                <div>
                    {this.state.items.map((item, index) => {
                        return <p ref={item.ref} 
                                  key={index}
                                  contentEditable 
                                  suppressContentEditableWarning 
                                  onKeyUp={e => this.handleParagraphKeyUp(e, index, item)}></p>
                    })}
                </div>
            </section>
        )
    }

    handleParagraphKeyUp = (e, index, item) => {
        if (e.which === 13) {
            let addition = this.paragraphTemplate()

            this.setState(state => {
                state.items.splice(index + 1, 0, addition)

                return {
                    blocks: state.items
                }
            }, () => {
                addition.ref.current.focus()

                /* clear out the br and div elements that the browser might auto-add on "enter" from the element that was focused when the "enter" key was used */
                this.state.items[index].ref.current.innerHTML = this.state.items[index].ref.current.innerHTML.replace(/<br\s*[\/]?>/gi, '').replace(/<[\/]?div>/gi, '')
            })

            return false
        }
    }

    paragraphTemplate = () => {
        return {
            ref: React.createRef()
        }
    }
}

export default MyComponent

这是上面的代码的jsfiddle

如果执行上述步骤,您将看到我遇到的问题。

如果您需要更多信息,请让我知道,谢谢!

PS请让我知道我是否可以对代码进行任何改进。 我已经在React中工作了很短的时间,并且希望得到关于如何使其更好/更清洁的反馈。

更新

P元素添加了key={index} 注意:这并不反映任何答案,它只是为了与ReactJS列表渲染保持一致而添加。

要渲染项目列表,React需要使用键来跟踪元素,请参见: https : //reactjs.org/docs/lists-and-keys.html

这是您更新的小提琴 ,可以正常工作。

<p ref={item.ref} 
   key={item.id}
   contentEditable 
   suppressContentEditableWarning 
   onKeyUp={e => this.handleParagraphKeyUp(e, 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM