Feel like I'm going crazy -- can't seem to get past this. Upon inputting any text, we immediately lose focus. Calling focus() on the ref appears to have absolutely no effect.
UpdatePage.js
export default class UpdatePage extends Component {
constructor(props) {
super(props);
const that = this;
auth.onAuthStateChanged((user) => {
db.collection('users/' + user.uid + '/updates')
.onSnapshot(function (querySnapshot) {
const updates = [];
querySnapshot.forEach(function (doc) {
const updateData = doc.data();
updates.push({...updateData, doc_id: doc.id});
});
that.setState({
updates: updates,
});
});
});
}
render() {
const todaysDate = new Date();
return (
<div>
<UpdateDeck date={todaysDate} {...this.state}/>
</div>
);
}
}
Update Deck
export default class UpdateDeck extends Component {
render() {
return <div key={this.props.date}>
<UpdateCard key={"A"} {...this.props}/>
<UpdateCard key={"B"} {...this.props}/>
</div>;
}
}
UpdateCard.js
export default class UpdateCard extends Component {
render() {
return <div>
<Card>
<ListGroup>
{this.props.updates
.map((update, i) => {
return <Update key={'Update_' + update.doc_id}
update={update}
{...this.props}/>;
})}
</ListGroup>
</Card>
</div>;
}
}
Update.js:
export default class Update extends Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
updateCard(doc_id, text) {
const ref = this.myRef.current;
db.collection(...).doc(doc_id).update(...)
.then(function () {
ref.focus();
})
}
render() {
return <ContentEditable
key={this.props.update.doc_id}
html={this.props.update.text}
innerRef={this.myRef}
disabled={false}
onChange={e => this.updateCard(this.props.update.doc_id, e.target.value)}
/>
}
}
Needless to say, the db.update()
function updates this.props.update.text
, but I'm wondering if this is the source of my issue since I'm not using state.
Using this ContentEditable npm library: https://www.npmjs.com/package/react-contenteditable
The reason that your focus is lost is because the component is getting remounted instead of re-rendered.
Now one reason this things happens is because you add a key prop to the component that changes between re-renders. When this happens React things that the component has changed and remounts it.
Now you add a key key={this.props.date}
on the div and I assume on each change on contentEditable date prop might ahve changed causing each and every child of it to remount
You also do not need a key prop unless you are returning elements from a loop
you could simply write your code like
export default class UpdateDeck extends Component {
render() {
return <div>
<UpdateCard {...this.props}/>
<UpdateCard {...this.props}/>
</div>;
}
}