reactjs - 当我单击新链接时,React-Router 不会重新渲染

标签 reactjs react-router

我有一些路线,但是当单击某些路线时,react-dom 不会重新渲染。以下是我的路线:

  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="/about" component={About}/>
    <Route path="/chat" component={Chat}>
        <Route path="/chat/:chat_room" component={Chat_Room}/>
    </Route>
    <Route path="/login" component={Login}/>
  </Route>

这是我的 /chat 组件:

export default React.createClass({
  loadChatRoomsFromServer: function() {
    $.ajax({
      url: '/chat_rooms',
      dataType: 'json',
      cache: false,
      success: function(data) {
        this.setState(data);
      }.bind(this),
      error: function(xhr, status, err) {
        console.error('/chat_rooms', status, err.toString());
      }.bind(this)
    });
  },
  getInitialState: function(){
      return {chat_rooms: []};
  },
  componentDidMount: function() {
      this.loadChatRoomsFromServer();
  },
  render: function() {
  var chat_nav_links = this.state.chat_rooms.map(function(rooms, i){
        return (
            <div key={i}>
              <li><NavLink to={"/chat/" + rooms.name}>{rooms.name}</NavLink></li>
            </div>
        );
    });
    return (
      <div>
          {chat_nav_links}
          {this.props.children}
        </div>
    );
  }
});

和我的 /chat_room 组件:

var ChatApp = React.createClass({

  getInitialState: function(){
      var chat_room = socket.subscribe(this.props.params.chat_room);
      var chat_room_channel = this.props.params.chat_room;
      chat_room.on('subscribeFail', function(err) {
        console.log('Failed to subscribe to '+chat_room_channel+' channel due to error: ' + err);
      });
      chat_room.watch(this.messageReceived);
      return {messages: []};
  },
  messageReceived: function(data){
      var messages = this.state.messages;
      var newMessages = messages.concat(data);
      this.setState({messages: newMessages});
  },

  render: function() {
    return (
      <div>
          <h2>{this.props.params.chat_room}</h2>
          <div className="container">
              <div className="messages">
                <MessagesList messages={this.state.messages}/>
              </div>
              <div className="actions">
                <ChatForm chat_room={this.props.params.chat_room}/>
              </div>
          </div>
      </div>
    )
  }
});

抱歉,代码量很大,我是从 Angular 来学习 React 的,目前还不完全确定哪些代码片段是相关的。所以请耐心等待。

问题是,假设我有 3 个 chat_rooms Volley 、网球、足球。如果我先点击“足球”,它完全没问题并且工作完美,但如果我点击“网球”链接,react-dom 键不会改变,我仍在足球 channel 中讲话。

现在我可以换房间了,但我必须转到 /about,然后返回并单击 /chat/tennis 从足球更改为网球。

我真的很想远离使用 Redux/Flux,因为我计划转向 MobX,我假设我没有正确改变状态,所以它没有更新 dom,但我已经坚持这个了几天了,我不清楚我做错了什么。谢谢!

最佳答案

当您单击新的聊天室链接时,ChatRoom 组件仍保持安装状态:此处唯一更改的是聊天室 ID,您的组件通过 props 接收该 ID。

要使其正常工作,您只需在 ChatRoom 组件中设置某些组件的生命周期方法(有关组件生命周期方法的更多信息 here ):

var ChatRoom = React.createClass({
    getInitialState: function() {  // sets initial state only
        return {messages: []};
    },

    componentDidMount: function() {  // sets-up subscription after 1st rendering
        this.subscribeToChatRoom(this.props.params.chat_room);
    },

    componentWillReceiveProps: function(nextProps) {  // when props change!
        if (nextProps.params.chat_room !== this.props.params.chat_room) {
            // reinits state for next rendering:
            this.setState({messages: []});
            // cleans-up previous subscription:
            this.unsubscribeToChatRoom(this.props.params.chat_room);
            // sets-up new subscription:
            this.subscribeToChatRoom(nextProps.params.chat_room);
        }
    },

    componentWillUnmount: function() {  // performs some clean-up when leaving
        this.unsubscribeToChatRoom(this.props.params.chat_room);
    },

    subscribeToChatRoom: function(chatRoomId) {
        var chat_room = socket.subscribe(chatRoomId);
        chat_room.on('subscribeFail', function(err) {
            console.log('Failed to subscribe to ' + chatRoomId
                + ' channel due to error: ' + err);
        });
        chat_room.watch(this.messageReceived);
    },

    unsubscribeToChatRoom: function(chatRoomId) {
        // socket un-subscription
    },

    messageReceived: function(data) {
        var messages = this.state.messages;
        var newMessages = messages.concat(data);
        this.setState({messages: newMessages});
    },

    render: function() {
        return (
            <div>
                <h2>{this.props.params.chat_room}</h2>
                <div className="container">
                    <div className="messages">
                        <MessagesList messages={this.state.messages} />
                    </div>
                    <div className="actions">
                        <ChatForm chat_room={this.props.params.chat_room} />
                    </div>
                </div>
            </div>
        )
    }
});

关于reactjs - 当我单击新链接时,React-Router 不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36298011/

相关文章:

reactjs - 警告 : Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed

javascript - 在 React 中获取路由参数

javascript - 使用 react 路由器 react HOC

javascript - 如何获取新数据以响应 Redux 对 React Router 的更改?

javascript - React/Flux 和 xhr/路由/缓存

javascript - 如何使用 Material UI 默认组件

javascript - react 路由器公共(public)路径url

reactjs - .net 核心 2.1 与 react 测试

reactjs - 将react-router与mobx状态同步

reactjs - 在 React 应用程序中分离两个不同的 UI