我尝试使用websockets来实现聊天应用程序之类的东西。但是当websocket收到消息时,没有组件正在重新渲染。请查看我的代码
# The main ancestor, chat application
@Chat = React.createClass
componentWillMount: ->
@setState signals: [] # the list of signals received by websockets
socket = new WebSocket('ws://localhost:19108')
socket.onmessage = (event) =>
@state.signals.push { message: event.data, direction: 'in' }
console.log @state.signals # it regularly write a message to console after receiving socket message
@setState socket: socket
render: ->
<div>
<div className="row">
<div className="col-md-12">
<SignalList signals={@state.signals} /> # I pass a signals here
</div>
</div>
</div>
$ ->
React.render(<Chat />, document.getElementById('container'))
信号列表现在只是为了显示props
的变化,但没有成功。它仍然是一个空数组
@SignalList = React.createClass
render: ->
<div>{ @props }</div>
我希望在websockets收到的每条消息后重新呈现props
。我怎么能这样做?
答案 0 :(得分:3)
您不应该直接改变@state
,而是使用setState
将状态更新排入队列,一旦执行,将导致组件重新呈现。您应该在大多数情况下将@state
及其值视为只读。
在您的情况下,请替换
@state.signals.push { message: event.data, direction: 'in' }
与
@setState signals: @state.signals.concat([{ message: event.data, direction: 'in' }])
与Array::push
不同,Array::concat
的好处是不会改变源数组,这意味着@state.signals
保持不变,直到状态更新完成。
答案 1 :(得分:2)
在onmessage
回调中,您直接操纵state.signals
而不是致电setState
。
尝试:
socket.onmessage = (event) =>
signals = @state.signals
signals.push { message: event.data, direction: 'in' }
@setState signals: signals