message: Move message previews into RoomTile's state
  Now that it doesn't re-render without state updates, we should just wedge it into state.
diff: @@ -72,6 +72,7 @@ interface IState {
  selected: boolean;
  notificationsMenuPosition: PartialDOMRect;
  generalMenuPosition: PartialDOMRect;
  + messagePreview?: string;
  }
  const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomId}`;
  @@ -123,6 +124,9 @@ export default class RoomTile extends React.Component<IProps, IState> {
  selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId,
  notificationsMenuPosition: null,
  generalMenuPosition: null,
  +
  + // generatePreview() will return nothing if the user has previews disabled
  + messagePreview: this.generatePreview(),
  };
  ActiveRoomObserver.addListener(this.props.room.roomId, this.onActiveRoomUpdate);
  @@ -157,13 +161,13 @@ export default class RoomTile extends React.Component<IProps, IState> {
  // Whenever a prop change happens (or our parent updates) we can get told to update too. Try
  // to minimize that by seeing if anything actually changed.
  if (objectHasValueChange(this.props, nextProps)) {
  - console.log(`DIFF_PROPS@${this.props.room.roomId}`, objectDiff(this.props, nextProps));
  + console.log(`DIFF_PROPS@${this.props.room.roomId}`, JSON.stringify(objectDiff(this.props, nextProps)));
  return true;
  }
  // Do the same for state
  if (objectHasValueChange(this.state, nextState)) {
  - console.log(`DIFF_STATE@${this.props.room.roomId}`, objectDiff(this.state, nextState));
  + console.log(`DIFF_STATE@${this.props.room.roomId}`, JSON.stringify(objectDiff(this.state, nextState)));
  return true;
  }
  @@ -181,10 +185,19 @@ export default class RoomTile extends React.Component<IProps, IState> {
  private onRoomPreviewChanged = (room: Room) => {
  if (this.props.room && room.roomId === this.props.room.roomId) {
  - this.forceUpdate(); // we don't have any state to set, so just complain that we need an update
  + // generatePreview() will return nothing if the user has previews disabled
  + this.setState({messagePreview: this.generatePreview()});
  }
  };
  + private generatePreview(): string | null {
  + if (!this.showMessagePreview) {
  + return null;
  + }
  +
  + return MessagePreviewStore.instance.getPreviewForRoom(this.props.room, this.props.tag);
  + }
  +
  private scrollIntoView = () => {
  if (!this.roomTileRef.current) return;
  this.roomTileRef.current.scrollIntoView({
  @@ -520,19 +533,13 @@ export default class RoomTile extends React.Component<IProps, IState> {
  name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon
  let messagePreview = null;
  - if (this.showMessagePreview) {
  - // The preview store heavily caches this info, so should be safe to hammer.
  - const text = MessagePreviewStore.instance.getPreviewForRoom(this.props.room, this.props.tag);
  -
  - // Only show the preview if there is one to show.
  - if (text) {
  + if (this.showMessagePreview && this.state.messagePreview) {
  messagePreview = (
  <div className="mx_RoomTile_messagePreview" id={messagePreviewId(this.props.room.roomId)}>
  - {text}
  + {this.state.messagePreview}
  </div>
  );
  }
  - }
  const nameClasses = classNames({
  "mx_RoomTile_name": true,
  