Подтвердить что ты не робот

Как обновить компонент ReactJS на основе URL/пути с помощью React-Router

Как я могу обновить компонент ReactJS на основе URL/пути при использовании React-Router?

Код ниже работает, но это правильный способ сделать это? Кажется, что очень много кода, чтобы сделать простое обновление. Я надеялся, что в маршрутизаторе будет выполняться вызов API с поддержкой состояния, чтобы автоматически позаботиться об этом сценарии.

var MyHomeView = React.createClass({
   componentDidMount: function() {
        this.props.updateHeader(); 
   },

   render: function() {
      return (
         <div>
            <h2>Home</h2>
         </div>
      );
  } 
}); 


var MyAboutView = React.createClass({
   componentDidMount: function() {
        this.props.updateHeader(); 
   },

  render: function() {
    return (
      <div className="my-page-text">
        <h2>About</h2>
      </div>
    );
  }
});


var MyHeader = React.createClass({
  mixins: [ CurrentPath ],

  getInitialState: function() {
    return {
       myPath: "about",
       classes: "ion-ios7-information"
    };
  },   

   updateHeader: function() {    
      // Classnames refer to www.ionicons.com
     if (this.getCurrentPath() === "/") {
        this.setState( {myPath: "about" } );
        this.setState( {classes: "ion-ios7-information" } );
     } else {
        this.setState( {myPath: "/" } );
        this.setState( {classes: "ion-ios7-rewind" } );
     }      
   }, 

  render: function() {
    return (
       <Link to={this.state.myPath}>
          <i className={this.state.classes} />
       </Link>
    );
  }
});


var App = React.createClass({
   updateHeader: function() {
      this.refs.header.updateHeader();
   },

   render: function() {
      return (
         <div>
            <MyHeader ref="header" />

         <this.props.activeRouteHandler updateHeader={this.updateHeader} />
         </div>
      );
  } 
}); 


React.renderComponent((
  <Routes> 
    <Route path="/" handler={App}>
      <DefaultRoute handler={MyHomeView} />
      <Route name="about" handler={MyAboutView} />
    </Route>
  </Routes>
), document.body);
4b9b3361

Ответ 1

В response-router 2.0.0 вы можете использовать hashHistory или browserHistory:

browserHistory.listen(function(ev) {
  console.log('listen', ev.pathname);
});

<Router history={browserHistory}>{routes}</Router>

Ответ 3

Этот вопрос был открыт некоторое время, и кажется, что должно быть более простое решение, но я возьму удар и расскажу, что мы делаем в нашем приложении.

Мы используем архитектуру Flux, которая имеет представление о Магазинах, которые информируют компоненты, когда их состояние обновляется. В react-router у них есть PathStore, который хорошо вписывается в эту модель, поскольку при изменении URL-адреса он может уведомлять компоненты, которые заботятся и нуждаются в обновлении.

StoreListener, который мы используем в нашем приложении, общедоступен здесь: https://github.com/odysseyscience/react-flux-suppprt. Я должен был опубликовать NPM, но пока не знаю. Я сделаю это скоро, если вы сочтете это полезным.

Вот как мы используем наш StoreListener для прослушивания изменений в PathStore от react-router и как вы будете использовать его в своем MyHeader:

var StoreListener = require('path/to/StoreListener');
var PathStore = require ('react-router/modules/stores/PathStore');

var MyHeader = React.createClass({
  mixins: [
    StoreListener(PathStore)
  ],

  getStateFromStores: function() {
    return {
        path: PathStore.getCurrentPath()
    };
  },

  render: function() {
    var path = this.state.path;
    var myPath;
    var classes;

    if (this.state.path === "/") {
      myPath = 'about';
      classes = 'ion-ios7-information';
    } else {
      myPath = '/';
      classes = 'ion-ios7-rewind';
    } 

    return (
      <Link to={myPath}>
        <i className={classes} />
      </Link>
    );
  }
});

Это начинается с mixin, в котором говорится: "Я забочусь об изменениях в PathStore". Всякий раз, когда этот магазин (или любой прослушиваемый магазин) изменяется, на ваш компонент вызывается getStateFromStores(), чтобы извлечь данные из магазина, который вы хотите получить на this.state. Если/Когда эти данные изменяются, render() вызывается снова, и вы перечитываете this.state и применяете свои изменения.

Это наш шаблон для применения определенных "активных" классов CSS на вкладках заголовков или где-либо еще в приложении, которое зависит от текущего URL.

Обратите внимание, что мы используем webpack для объединения наших модулей CommonJS, поэтому могут быть некоторые предположения относительно среды, которая может/не работать для вас.

Я не отвечал на этот вопрос месяц назад, когда впервые увидел это, потому что предположил, что есть лучший способ, но, возможно, наше решение может помочь другим с той же проблемой.