I've a list with DOM elements that I map in the render function. Now, when I click a button I can add a new element, and I've a function that is working to do that. I push the element in the list in this way:

this.state.addedText.push(
    <div className="editable" id={idDiv} onChange={(e) => this._changeText(e)} contentEditable style={{display: "block", position: "absolute", fontWeight: "bold", backgroundColor: "rgba(0,0,0,.5)", wordWrap: "break-word", textAlign: "center", width: "100%", color: "white", top: "0px", borderTop: "1px solid white", borderBottom: "1px solid white"}}>
       {this.state.textDivAdded[nextItem]}
    </div>
 );

and then I call the forceUpdate. Now, the id of element is something like "editable_#" where # is the position in the array (so something like editable_1, editable_2 and so on..).

If, below the forceUpdate, I put console.log(document.getElementsByClassName("editable")) I can see the new element, but I can't get it. If I write console.log(document.getElementsByClassName("editable"))[0] I've "undefined".

This is how I render the list:

{this.state.addedText.length > 0 && this.state.addedText.map(v => {
  return (
      <Draggable defaultPosition={{x: 0, y: 0}} enableUserSelectHack={false} axis="both" bounds="parent">
         {v}
      </Draggable>
  )
})} 

As you can see the div that I add is "contentEditable", so I can change the text of it, and I need to add an eventlistener to get the "onChange", but I don't know how to get this element after the rendering, and also I need to focus it when I add it to the DOM.

Obiously, when I add a second element I can get the previous item added.

Some idea? Thank you!

1 Answers

2
Romain On Best Solutions

How about rethinking your design, the state would hold the value of the divs:

this.state = {
   texts: [];
}

...

{this.state.texts.length && this.state.texts.map((v,i) => {
  return (
      <Draggable key={i} ...>
         <div className="editable" onChange={(e) => this._changeText(i,e)} contentEditable ...>
          {v}
         </div>
      </Draggable>
  )
})} 

To add a text:

this.setState({
   texts: [...this.state.texts, 'whatever, coming from an array?']
});

To change text:

_changeText(i,e) {
   this.setState({
      texts: this.state.texts.map((t,j), => i == j ? e.target.value : t)
   });
}