TypeError: Cannot read property 'scrollIntoView' of null
class App extends Component {
constructor(props) {
super(props)
this.state = { text: "", messages: }
}
componentDidMount() {
const config = {
apiKey: "<api-key>",
authDomain: "<project-name>.firebaseapp.com",
databaseURL: "https://<project-name>.firebaseio.com",
projectId: "<project-name>",
storageBucket: "<project-name>.appspot.com",
messagingSenderId: "<sender-id>",
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
this.getMessages()
var database = firebase.database();
var ref = database.ref('messages');
}
onSubmit = event => {
if (event.charCode === 13 && this.state.text.trim() !== "") {
this.writeMessageToDB(this.state.text)
this.setState({ text: "" })
}
}
writeMessageToDB = () => {
firebase.database().ref('messages/').push({
text: this.state.text,
createdAt: createdAt,
user:{
_id: currentUser,
name:name
}
});
}
getMessages = () => {
var messagesDB = firebase
.database()
.ref("messages/")
.limitToLast(500)
messagesDB.on("value", snapshot => {
let newMessages =
snapshot.forEach(child => {
var message = child.val()
var yeah = dateFormat(message.createdAt,"dddd, mmmm dS, yyyy, h:MM:ss TT")
newMessages.push({ id: child.key, text: message.text,createdAt: yeah, names: message.name })
})
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
})
}
renderMessages = () => {
return this.state.messages.map(message => (
<ListItem>
<ListItemText className="chatList"
style={{ wordBreak: "break-word", backgroundColor: "#FFA1B5", borderRadius: "10px", width: "10px", padding: "5px" }}
primary={message.name+": "+message.text}
secondary={message.createdAt}
/>
</ListItem>
))
}
render() {
return (
<MuiThemeProvider theme={theme}>
<div style={mainCont}>
<label style={labelStyle} className="labelStyle"> Chat</label>
<div className="App" >
<ScrollToBottom className={ ROOT_CSS }>
<List>{this.renderMessages()}</List>
</ScrollToBottom>
<TextField className="txtFieldStyle"
autoFocus={true}
multiline={true}
rowsMax={3}
placeholder="Type something.."
onChange={event => this.setState({ text: event.target.value })}
value={this.state.text}
onKeyPress={this.onSubmit}
style={{ width: "350px", overflow: "hidden", marginLeft: "15px", fontSize: '63px', paddingBottom: '5px' }}
/>
<span ref={el => (this.bottomSpan = el)} />
</div>
</div>
</MuiThemeProvider>
)
}
}
export default App;
chat feature is working fine unless the user navigates to other pages and go back to the chat feature and attempts to send message through chat.
javascript reactjs
add a comment |
class App extends Component {
constructor(props) {
super(props)
this.state = { text: "", messages: }
}
componentDidMount() {
const config = {
apiKey: "<api-key>",
authDomain: "<project-name>.firebaseapp.com",
databaseURL: "https://<project-name>.firebaseio.com",
projectId: "<project-name>",
storageBucket: "<project-name>.appspot.com",
messagingSenderId: "<sender-id>",
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
this.getMessages()
var database = firebase.database();
var ref = database.ref('messages');
}
onSubmit = event => {
if (event.charCode === 13 && this.state.text.trim() !== "") {
this.writeMessageToDB(this.state.text)
this.setState({ text: "" })
}
}
writeMessageToDB = () => {
firebase.database().ref('messages/').push({
text: this.state.text,
createdAt: createdAt,
user:{
_id: currentUser,
name:name
}
});
}
getMessages = () => {
var messagesDB = firebase
.database()
.ref("messages/")
.limitToLast(500)
messagesDB.on("value", snapshot => {
let newMessages =
snapshot.forEach(child => {
var message = child.val()
var yeah = dateFormat(message.createdAt,"dddd, mmmm dS, yyyy, h:MM:ss TT")
newMessages.push({ id: child.key, text: message.text,createdAt: yeah, names: message.name })
})
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
})
}
renderMessages = () => {
return this.state.messages.map(message => (
<ListItem>
<ListItemText className="chatList"
style={{ wordBreak: "break-word", backgroundColor: "#FFA1B5", borderRadius: "10px", width: "10px", padding: "5px" }}
primary={message.name+": "+message.text}
secondary={message.createdAt}
/>
</ListItem>
))
}
render() {
return (
<MuiThemeProvider theme={theme}>
<div style={mainCont}>
<label style={labelStyle} className="labelStyle"> Chat</label>
<div className="App" >
<ScrollToBottom className={ ROOT_CSS }>
<List>{this.renderMessages()}</List>
</ScrollToBottom>
<TextField className="txtFieldStyle"
autoFocus={true}
multiline={true}
rowsMax={3}
placeholder="Type something.."
onChange={event => this.setState({ text: event.target.value })}
value={this.state.text}
onKeyPress={this.onSubmit}
style={{ width: "350px", overflow: "hidden", marginLeft: "15px", fontSize: '63px', paddingBottom: '5px' }}
/>
<span ref={el => (this.bottomSpan = el)} />
</div>
</div>
</MuiThemeProvider>
)
}
}
export default App;
chat feature is working fine unless the user navigates to other pages and go back to the chat feature and attempts to send message through chat.
javascript reactjs
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24
add a comment |
class App extends Component {
constructor(props) {
super(props)
this.state = { text: "", messages: }
}
componentDidMount() {
const config = {
apiKey: "<api-key>",
authDomain: "<project-name>.firebaseapp.com",
databaseURL: "https://<project-name>.firebaseio.com",
projectId: "<project-name>",
storageBucket: "<project-name>.appspot.com",
messagingSenderId: "<sender-id>",
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
this.getMessages()
var database = firebase.database();
var ref = database.ref('messages');
}
onSubmit = event => {
if (event.charCode === 13 && this.state.text.trim() !== "") {
this.writeMessageToDB(this.state.text)
this.setState({ text: "" })
}
}
writeMessageToDB = () => {
firebase.database().ref('messages/').push({
text: this.state.text,
createdAt: createdAt,
user:{
_id: currentUser,
name:name
}
});
}
getMessages = () => {
var messagesDB = firebase
.database()
.ref("messages/")
.limitToLast(500)
messagesDB.on("value", snapshot => {
let newMessages =
snapshot.forEach(child => {
var message = child.val()
var yeah = dateFormat(message.createdAt,"dddd, mmmm dS, yyyy, h:MM:ss TT")
newMessages.push({ id: child.key, text: message.text,createdAt: yeah, names: message.name })
})
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
})
}
renderMessages = () => {
return this.state.messages.map(message => (
<ListItem>
<ListItemText className="chatList"
style={{ wordBreak: "break-word", backgroundColor: "#FFA1B5", borderRadius: "10px", width: "10px", padding: "5px" }}
primary={message.name+": "+message.text}
secondary={message.createdAt}
/>
</ListItem>
))
}
render() {
return (
<MuiThemeProvider theme={theme}>
<div style={mainCont}>
<label style={labelStyle} className="labelStyle"> Chat</label>
<div className="App" >
<ScrollToBottom className={ ROOT_CSS }>
<List>{this.renderMessages()}</List>
</ScrollToBottom>
<TextField className="txtFieldStyle"
autoFocus={true}
multiline={true}
rowsMax={3}
placeholder="Type something.."
onChange={event => this.setState({ text: event.target.value })}
value={this.state.text}
onKeyPress={this.onSubmit}
style={{ width: "350px", overflow: "hidden", marginLeft: "15px", fontSize: '63px', paddingBottom: '5px' }}
/>
<span ref={el => (this.bottomSpan = el)} />
</div>
</div>
</MuiThemeProvider>
)
}
}
export default App;
chat feature is working fine unless the user navigates to other pages and go back to the chat feature and attempts to send message through chat.
javascript reactjs
class App extends Component {
constructor(props) {
super(props)
this.state = { text: "", messages: }
}
componentDidMount() {
const config = {
apiKey: "<api-key>",
authDomain: "<project-name>.firebaseapp.com",
databaseURL: "https://<project-name>.firebaseio.com",
projectId: "<project-name>",
storageBucket: "<project-name>.appspot.com",
messagingSenderId: "<sender-id>",
};
if (!firebase.apps.length) {
firebase.initializeApp(config);
}
this.getMessages()
var database = firebase.database();
var ref = database.ref('messages');
}
onSubmit = event => {
if (event.charCode === 13 && this.state.text.trim() !== "") {
this.writeMessageToDB(this.state.text)
this.setState({ text: "" })
}
}
writeMessageToDB = () => {
firebase.database().ref('messages/').push({
text: this.state.text,
createdAt: createdAt,
user:{
_id: currentUser,
name:name
}
});
}
getMessages = () => {
var messagesDB = firebase
.database()
.ref("messages/")
.limitToLast(500)
messagesDB.on("value", snapshot => {
let newMessages =
snapshot.forEach(child => {
var message = child.val()
var yeah = dateFormat(message.createdAt,"dddd, mmmm dS, yyyy, h:MM:ss TT")
newMessages.push({ id: child.key, text: message.text,createdAt: yeah, names: message.name })
})
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
})
}
renderMessages = () => {
return this.state.messages.map(message => (
<ListItem>
<ListItemText className="chatList"
style={{ wordBreak: "break-word", backgroundColor: "#FFA1B5", borderRadius: "10px", width: "10px", padding: "5px" }}
primary={message.name+": "+message.text}
secondary={message.createdAt}
/>
</ListItem>
))
}
render() {
return (
<MuiThemeProvider theme={theme}>
<div style={mainCont}>
<label style={labelStyle} className="labelStyle"> Chat</label>
<div className="App" >
<ScrollToBottom className={ ROOT_CSS }>
<List>{this.renderMessages()}</List>
</ScrollToBottom>
<TextField className="txtFieldStyle"
autoFocus={true}
multiline={true}
rowsMax={3}
placeholder="Type something.."
onChange={event => this.setState({ text: event.target.value })}
value={this.state.text}
onKeyPress={this.onSubmit}
style={{ width: "350px", overflow: "hidden", marginLeft: "15px", fontSize: '63px', paddingBottom: '5px' }}
/>
<span ref={el => (this.bottomSpan = el)} />
</div>
</div>
</MuiThemeProvider>
)
}
}
export default App;
chat feature is working fine unless the user navigates to other pages and go back to the chat feature and attempts to send message through chat.
javascript reactjs
javascript reactjs
edited Jan 1 at 14:52
Ian Kemp
16.9k126999
16.9k126999
asked Jan 1 at 6:54
Paul D. DangoPaul D. Dango
85
85
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24
add a comment |
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24
add a comment |
1 Answer
1
active
oldest
votes
The following two lines in App.componentDidMount()
are a potential race condition.
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
The App
state may be mutated earlier to begin a render cycle so that the bottomSpan
is set to reference the element before this.bottomSpan.scrollIntoView()
is called.
However, this.bottomSpan.scrollIntoView()
is never guaranteed to be called after state is updated.
Remember that setState
doesn't always immediately mutate the state of the component. [1]
You can scroll the referenced element into view after state is mutated by doing that in a callback passed as the second argument to state.
this.setState(
{ messages: newMessages },
() => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993583%2ftypeerror-cannot-read-property-scrollintoview-of-null%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The following two lines in App.componentDidMount()
are a potential race condition.
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
The App
state may be mutated earlier to begin a render cycle so that the bottomSpan
is set to reference the element before this.bottomSpan.scrollIntoView()
is called.
However, this.bottomSpan.scrollIntoView()
is never guaranteed to be called after state is updated.
Remember that setState
doesn't always immediately mutate the state of the component. [1]
You can scroll the referenced element into view after state is mutated by doing that in a callback passed as the second argument to state.
this.setState(
{ messages: newMessages },
() => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)
add a comment |
The following two lines in App.componentDidMount()
are a potential race condition.
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
The App
state may be mutated earlier to begin a render cycle so that the bottomSpan
is set to reference the element before this.bottomSpan.scrollIntoView()
is called.
However, this.bottomSpan.scrollIntoView()
is never guaranteed to be called after state is updated.
Remember that setState
doesn't always immediately mutate the state of the component. [1]
You can scroll the referenced element into view after state is mutated by doing that in a callback passed as the second argument to state.
this.setState(
{ messages: newMessages },
() => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)
add a comment |
The following two lines in App.componentDidMount()
are a potential race condition.
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
The App
state may be mutated earlier to begin a render cycle so that the bottomSpan
is set to reference the element before this.bottomSpan.scrollIntoView()
is called.
However, this.bottomSpan.scrollIntoView()
is never guaranteed to be called after state is updated.
Remember that setState
doesn't always immediately mutate the state of the component. [1]
You can scroll the referenced element into view after state is mutated by doing that in a callback passed as the second argument to state.
this.setState(
{ messages: newMessages },
() => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)
The following two lines in App.componentDidMount()
are a potential race condition.
this.setState({ messages: newMessages })
this.bottomSpan.scrollIntoView({ behavior: "smooth" })
The App
state may be mutated earlier to begin a render cycle so that the bottomSpan
is set to reference the element before this.bottomSpan.scrollIntoView()
is called.
However, this.bottomSpan.scrollIntoView()
is never guaranteed to be called after state is updated.
Remember that setState
doesn't always immediately mutate the state of the component. [1]
You can scroll the referenced element into view after state is mutated by doing that in a callback passed as the second argument to state.
this.setState(
{ messages: newMessages },
() => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)
answered Jan 1 at 11:32
Oluwafemi SuleOluwafemi Sule
11.8k1532
11.8k1532
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993583%2ftypeerror-cannot-read-property-scrollintoview-of-null%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You should bind your event handling methods to this at constructor
– El.
Jan 1 at 11:24