javascript - 类型错误 : Cannot read property 'scrollIntoView' of null

标签 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">&nbsp;&nbsp;&nbsp;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;

聊天功能工作正常,除非用户导航到其他页面并返回聊天功能并尝试通过聊天发送消息。

最佳答案

App.componentDidMount() 中的以下两行是潜在的竞争条件。

    this.setState({ messages: newMessages })
    this.bottomSpan.scrollIntoView({ behavior: "smooth" })

App 状态可能会提前发生变化以开始渲染周期,以便将 bottomSpan 设置为在 this.bottomSpan.scrollIntoView() 之前引用该元素 被调用。

但是,this.bottomSpan.scrollIntoView() 永远不能保证在状态更新后被调用。
请记住,setState 并不总是立即改变组件的状态。 [1]

在状态发生变化后,您可以通过在作为第二个参数传递给状态的回调中执行此操作,将引用的元素滚动到 View 中。

this.setState(
  { messages: newMessages }, 
  () => this.bottomSpan.scrollIntoView({ behavior: "smooth" })
)

关于javascript - 类型错误 : Cannot read property 'scrollIntoView' of null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53993583/

相关文章:

javascript - ReactJS、Redux 和 DexieJS (IndexedDB) - 隐身模式和 Chrome v69 中的错误

javascript - 创建用于从 API 获取数据的 altjs 流量存储

javascript - 无法修改 AngularJS 中工厂方法上的变量

javascript - AlpacaJS:动态表行中的可观察引用字段

javascript - 浏览器不处理报价参数

javascript - clearTimeout 动态更新定时器

javascript - React 组件加载模式(或反模式?)

javascript - 具有动态创建功能的 React 组件

javascript - 为什么我的 PhantomJS 脚本挂起?

javascript - 使用 React 发出和处理全局事件