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

时间:2018-10-18 16:17:41

标签: javascript reactjs jsx contenteditable

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

目标

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

在每个contentEditable段落元素上,监听onKeyUp事件。如果e.which中使用的键是enter(13)键,请使用所键入元素的索引将新项添加到this.state.items,以便使用以下命令在该索引之后插入新元素splice

看到预期结果了吗?

不。而是在渲染新添加的项目时将其放置在循环的末尾。

示例情况和重现步骤:

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

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

P

这是一个jsfiddle,上面有代码。

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

如果需要进一步的信息,请告诉我!

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

已更新

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 添加到key={index}元素中。注意:这并不反映任何答案,它只是为了与ReactJS列表呈现保持一致而添加。

1 个答案:

答案 0 :(得分:2)

要显示项目列表,React需要按键来跟踪元素 看到这个:https://reactjs.org/docs/lists-and-keys.html

这是您更新的fiddle的正常工作。.

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