Ответ 1
В response-router 2.0.0 вы можете использовать hashHistory или browserHistory:
browserHistory.listen(function(ev) {
console.log('listen', ev.pathname);
});
<Router history={browserHistory}>{routes}</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);
В response-router 2.0.0 вы можете использовать hashHistory или browserHistory:
browserHistory.listen(function(ev) {
console.log('listen', ev.pathname);
});
<Router history={browserHistory}>{routes}</Router>
Это обновление было обновлено, если вы работаете с agent-маршрутизатором > v11.0.
Вы можете прочитать подробности здесь
TL;DR:
// v0.11.x
var Something = React.createClass({
mixins: [ Router.State ],
render: function () {
var path = this.getPath();
}
});
Для полного API State
: https://github.com/rackt/react-router/blob/master/doc/04%20Mixins/State.md
Этот вопрос был открыт некоторое время, и кажется, что должно быть более простое решение, но я возьму удар и расскажу, что мы делаем в нашем приложении.
Мы используем архитектуру 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, поэтому могут быть некоторые предположения относительно среды, которая может/не работать для вас.
Я не отвечал на этот вопрос месяц назад, когда впервые увидел это, потому что предположил, что есть лучший способ, но, возможно, наше решение может помочь другим с той же проблемой.