I am new to react,I am just getting content from contentieditable when user click on a button and contentEditable should appear with focus.But I could focus contenteditable this.refs returns an empty object and there are similar question on stackoverflow but nothing helped me.I have no idea why this.refs returns an empty object.Thanks in advance
import React, {Component} from 'react';
import {connect} from 'react-redux';
import trimHtml from 'trim-html'
import * as privateTodoActions from '../../../actions/todoActions'
class PersonelTodo extends Component{
constructor(props){
super(props);
this.state = {
newTodo:false,
currentTodo:""
};
}
componentDidMount(){
this.props.fetchPrivateTodos();
}
newTodo = () => {
if(this.state.newTodo){
this.setState({
newTodo:false
})
}else{
this.setState({
newTodo:true
});
console.log(this.refs) // empty Object {}
}
};
handleTodoInput = (e) => {
this.setState({
currentTodo:e.target.innerHTML
})
};
postTodo = () => {
if(this.state.currentTodo !== ""){
let payload = {
todoCon:this.state.currentTodo.replace(/(<([^>]+)>)/ig, ""),
isPrivate:true
};
this.props.postPrivateTodo(payload);
this.refs.todoInput.innerHTML = "";
this.setState({
currentTodo:""
})
}
};
handleShorcut = (e) => {
if(e.keyCode === 13 && e.ctrlKey){
e.preventDefault();
this.refs.todoInput.innerHTML = "";
this.postTodo()
}
};
renderAllTodos(){
return this.props.privateTodo.get('todoList').map(data => {
let {html} = trimHtml( data.todoCon, { limit: 180 })
return(
<div key={data._id} className="UniquesingleTodo singleTodo">
{/*<div className="labels">*/}
{/*<div className="redLabel ColorLabel">*/}
{/*</div>*/}
{/*<div className="GreenLabel ColorLabel">*/}
{/*</div>*/}
{/*</div>*/}
<div className="todoContentEdit" dangerouslySetInnerHTML={{__html: html}} />
</div>
)
})
}
render(){
return(
<div className="todoContainer">
<div className="PersonelTodoSection">
<div className="PersonelSectionTitle">
<div className="IconSingleTodoCat">
<svg className="svg-icon" viewBox="0 0 20 20">
<path d="M17.638,6.181h-3.844C13.581,4.273,11.963,2.786,10,2.786c-1.962,0-3.581,1.487-3.793,3.395H2.362c-0.233,0-0.424,0.191-0.424,0.424v10.184c0,0.232,0.191,0.424,0.424,0.424h15.276c0.234,0,0.425-0.191,0.425-0.424V6.605C18.062,6.372,17.872,6.181,17.638,6.181 M13.395,9.151c0.234,0,0.425,0.191,0.425,0.424S13.629,10,13.395,10c-0.232,0-0.424-0.191-0.424-0.424S13.162,9.151,13.395,9.151 M10,3.635c1.493,0,2.729,1.109,2.936,2.546H7.064C7.271,4.744,8.506,3.635,10,3.635 M6.605,9.151c0.233,0,0.424,0.191,0.424,0.424S6.838,10,6.605,10c-0.233,0-0.424-0.191-0.424-0.424S6.372,9.151,6.605,9.151 M17.214,16.365H2.786V7.029h3.395v1.347C5.687,8.552,5.332,9.021,5.332,9.575c0,0.703,0.571,1.273,1.273,1.273c0.702,0,1.273-0.57,1.273-1.273c0-0.554-0.354-1.023-0.849-1.199V7.029h5.941v1.347c-0.495,0.176-0.849,0.645-0.849,1.199c0,0.703,0.57,1.273,1.272,1.273s1.273-0.57,1.273-1.273c0-0.554-0.354-1.023-0.849-1.199V7.029h3.395V16.365z" />
</svg>
</div>
<p>Personel</p>
<button onClick={this.newTodo}>Add</button>
</div>
<div className="PersonalTodoContainer">
{this.renderAllTodos()}
{this.state.newTodo ? <div className="todoInput--unique">
<div onKeyDown={this.handleShorcut} onInput={this.handleTodoInput} spellCheck="false" ref={(input) => {this.todoInput = input}} contentEditable="true" className="inputCon"/>
<div className="newTodoBut">
<button onClick={this.postTodo} className="addtodobtn">Add</button>
<button onClick={this.postTodo} className="closeAddtodo">
<svg fill="#fff" className="svg-icon" viewBox="0 0 20 20">
<path d="M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z" />
</svg>
</button>
</div>
</div> : ""}
</div>
</div>
</div>
)
}
}
function mapStateToProps(state) {
return{
privateTodo:state.privateTodo
}
}
export default connect(mapStateToProps,privateTodoActions)(PersonelTodo)
The way you get the ref in your ref callback, you have to access it with this.todoInput instead of this.refs.todoInput. As far as I am aware, it would only hold the ref in the refs object if you do something like: ref="todoInput" on your component.