Используйте функцию встроенного getattr
, чтобы получить атрибут объекта по имени. Измените имя по мере необходимости.
obj.spam = 'eggs'
name = 'spam'
getattr(obj, name) # returns 'eggs'
React Router v4
С v4 React Router существует три подхода, которые вы можете предпринять для программной маршрутизации внутри компонентов.
- Используйте
withRouter
компонент более высокого порядка.- Используйте композицию и выведите
<Route>
- Используйте
context
.Реагируйте Маршрутизатор в основном является оберткой вокруг библиотеки
history
.history
взаимодействует с браузеромwindow.history
для вас с его браузером и историями хэша. Он также обеспечивает историю памяти, которая полезна для сред, которые не имеют глобальной истории. Это особенно полезно в разработке мобильных приложений (react-native
) и модульном тестировании с помощью узла.Экземпляр
history
имеет два способа навигации:push
иreplace
. Если вы думаете оhistory
как о массиве посещенных мест,push
добавит новое место в массив, аreplace
заменит текущее местоположение в массиве новым. Обычно вы будете использовать методpush
во время навигации.В более ранних версиях React Router вам нужно было создать свой собственный экземпляр
history
, но в v4<BrowserRouter>
,<HashRouter>
и<MemoryRouter>
будут созданы для вас браузер, хэш и экземпляры памяти. React Router делает свойства и методы экземпляраhistory
, связанные с вашим маршрутизатором, доступными через контекст под объектомrouter
.1. Используйте
withRouter
компонент более высокого порядкакод
withRouter
высшего порядка компонент будет впрыскиватьhistory
объект в качестве опоры компонента. Это позволяет вам получить доступ к методамpush
иreplace
, не имея дело сcontext
.import { withRouter } from 'react-router-dom' // this also works with react-router-native const Button = withRouter(({ history }) => ( <button type='button' onClick={() => { history.push('/new-location') }} > Click Me! </button> ))
2. Используйте композицию и рендерите
<Route>
Компонент
<Route>
предназначен не только для сопоставления местоположений. Вы можете сделать беспроблемный маршрут, и он всегда будет соответствовать текущему местоположению. Компонент<Route>
передает те же реквизиты, что иwithRouter
, поэтому вы сможете получить доступ кhistory
методам с помощьюhistory
prop.import { Route } from 'react-router-dom' const Button = () => ( <Route render={({ history}) => ( <button type='button' onClick={() => { history.push('/new-location') }} > Click Me! </button> )} /> )
3. Используйте контекст *
* Но вы, вероятно, не должны
Последний вариант - это тот, который вы должны использовать, только если вам комфортно работать с моделью context React] , Хотя контекст является опцией, следует подчеркнуть, что контекст является нестабильным API, и в React есть раздел «Почему бы не использовать контекст в своей документации. Поэтому используйте на свой страх и риск!
const Button = (props, context) => ( <button type='button' onClick={() => { // context.history.push === history.push context.history.push('/new-location') }} > Click Me! </button> ) // you need to specify the context type so that it // is available within the component Button.contextTypes = { history: React.PropTypes.shape({ push: React.PropTypes.func.isRequired }) }
1 и 2 являются простейшими вариантами для реализации, поэтому для большинства случаев использования они являются вашими лучшими ставками.
Возможно, это не лучшее решение, но оно выполняет свою работу:
import { Link } from 'react-router-dom';
// create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
В принципе логика, связанная с одним действием (в данном случае удаление почты), вызовет триггер для перенаправления. Это не идеально, потому что вы добавите триггер узла DOM в свою разметку, чтобы вы могли удобно вызвать его, когда это необходимо. Кроме того, вы будете напрямую взаимодействовать с DOM, который в компоненте React может быть нежелательным.
Тем не менее этот тип перенаправления не требуется часто. Таким образом, одна или две дополнительные скрытые ссылки в вашей разметке компонента не будут сильно задевать, особенно если вы дадите им значимые имена.
history
, как указано в @Bobby. Вы могли i> использовать context.router
, но вам действительно сложно выполнить тестирование этих компонентов как создание экземпляра just i>, который не будет иметь этот компонент в контексте.
– George Mauer
24 January 2016 в 22:01
import { browserHistory } from './react-router'
, но вместо этого создает историю, используя import createBrowserHistory from 'history/lib/createBrowserHistory'
. Позже вы можете получить доступ к history
из реквизитов компонентов: this.props.history('/some/path')
– Ricardo Pedroni
3 February 2016 в 16:57
history
для любого подхода сейчас
– George Mauer
22 March 2016 в 23:31
var browserHistory = require('react-router').browserHistory; browserHistory.goBack();
– Bobby
28 April 2016 в 04:19
push
изменяет только URL-адрес, фактически не изменяет страницу. Для этого импортируйте browserHistory
из react-router
и используйте browserHistory.push('/my-cool-path')
. К сожалению, это не очень легко найти. [Д0] github.com/reactjs/react-router/blob/master/docs/guides/…
– Andrew Samuelsen
8 June 2016 в 06:43
react-router
v4
– spik3s
6 October 2016 в 11:25
200 OK
вместо кода 30x
. Как я могу исправить эту проблему?
– Muhammad Ateeq Azam
22 December 2016 в 14:44
React-Router 4.x Ответ:
В конце концов, мне нравится иметь один объект истории, в котором я могу переносить даже внешние компоненты. Мне нравится делать один файл history.js, который я импортирую по требованию, и просто манипулировать им.
Вам просто нужно изменить
BrowserRouter
на Router и указать поддержку истории. Это ничего не изменяет для вас, кроме того, что у вас есть свой собственный объект истории, который вы можете манипулировать по своему усмотрению.Вам необходимо установить history , библиотеку, используемую
react-router
.Пример использования, нотация ES6:
history.js
import createBrowserHistory from 'history/createBrowserHistory' export default createBrowserHistory()
BasicComponent.js
import React, { Component } from 'react'; import history from './history'; class BasicComponent extends Component { goToIndex(e){ e.preventDefault(); history.push('/'); } render(){ return <a href="#" onClick={this.goToIndex}>Previous</a>; } }
] EDIT 16 апреля 2018 года:
Если вам нужно перейти от компонента, который фактически отображается с помощью компонента
Route
, вы также можете получить доступ к истории из реквизита, например:BasicComponent.js
import React, { Component } from 'react'; class BasicComponent extends Component { navigate(e){ e.preventDefault(); this.props.history.push('/url'); } render(){ return <a href="#" onClick={this.navigate}>Previous</a>; } }
Router
вместо BrowserRouter
. BrowserRouter
создает и поддерживает для вас объект history
. Вы не должны по умолчанию создавать свои собственные, только если вам нужна «глубокая интеграция с инструментами управления государственными службами, такими как Redux.» reacttraining.com/react-router/web/api/Router
– bobbyz
7 November 2017 в 23:09
this.props.history
, я еще не нашел решение, которое может помочь мне сделать такую вещь в классе, который не является компонентом или каким-либо другим инструментом, который не построен как реактивный компонент, к которому вы можете передать реквизит. Спасибо за ваш отзыв :)
– Eric Martin
15 December 2017 в 10:38
React-Router V4
, если вы используете версию 4, тогда вы можете использовать мою библиотеку (Shameless plug), где вы просто отправляете действие, и все просто работает!
dispatch(navigateTo("/aboutUs"));
В React-Router v4 и ES6
blockquote>Вы можете использовать
withRouter
иthis.props.history.push
.import {withRouter} from 'react-router-dom'; class Home extends Component { componentDidMount() { this.props.history.push('/redirect-to'); } } export default withRouter(Home);
Чтобы использовать withRouter
с компонентом на основе класса, попробуйте что-то вроде этого ниже. Не забудьте изменить выражение экспорта для использования withRouter
:
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
Пожалуйста, найдите ниже рабочий код: Это очень простой способ навигации с помощью реагирующего маршрутизатора:
class Register extends React.Component {
state = {
toDashboard: false,
}
handleSubmit = (user) => {
saveUser(user)
.then(() => this.setState(() => ({
toDashboard: true
})))
}
render() {
if (this.state.toDashboard === true) {
return <Redirect to='/dashboard' />
}
return (
<div>
<h1>Register</h1>
<Form onSubmit={this.handleSubmit} />
</div>
)
}
}
& lt; Redirect /> is
Композитный ✅ Декларативный ✅ пользовательское событие -> изменение состояния -> повторная рендеринга ✅
blockquote>Регистрирующий компонент визуализируется React Router, наш код может выглядеть следующим образом:
class Register extends React.Component { handleSubmit = (user) => { saveUser(user).then(() => this.props.history.push('/dashboard') )) } render() { return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ) } }
, добавляя withRouter, это будет выглядеть так
import { withRouter } from 'react-router-dom' class Register extends React.Component { handleSubmit = (user) => { saveUser(user).then(() => this.props.history.push('/dashboard') )) } render() { return ( <div> <h1>Register</h1> <Form onSubmit={this.handleSubmit} /> </div> ) } } export default withRouter(Register)
Существует два способа программной навигации с помощью React Router - и history.push. Что вы используете, в основном зависит от вас и вашего конкретного варианта использования, хотя я стараюсь использовать Redirect.
Не может быть лучшим подходом, но ... Используя response-router v4, следующий машинописный документ может дать представление для некоторых.
В представленном компоненте ниже, например. Объект LoginPage
, router
доступен и просто вызывает router.transitionTo('/homepage')
для навигации.
Код навигации был взят из https://react-router.now.sh/Match .
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
interface MatchWithPropsInterface {
component: typeof React.Component,
router: Router,
history: History,
exactly?: any,
pattern: string
}
class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
render() {
return(
<Match {...this.props} render={(matchProps) => (
React.createElement(this.props.component, this.props)
)}
/>
)
}
}
ReactDOM.render(
<Router>
{({ router }) => (
<div>
<MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
<Miss component={NotFoundView} />
</div>
)}
</Router>,
document.getElementById('app')
);
Просто используйте this.props.history.push('/where/to/go');
с React-Router v4 на горизонте, теперь есть новый способ сделать это.
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
response-lego - пример приложения, показывающий , как использовать / обновлять реактивный маршрутизатор , и он включает пример функциональных тестов, которые перемещаются в приложении.
В ответном маршрутизаторе v4. Я следую этому двум способом маршрутизации программно.
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
Номер два
Заменяет текущую запись в стеке истории
Чтобы получить историю в реквизитах, вам может понадобиться обернуть ваш компонент с помощью
withRouter https://reacttraining.com/react-router/core/api/withRouter
Если произойдет сопряжение RR4 с редукцией через response-router-redux , используйте действия с маршрутизацией, которые также могут быть созданы создателями из react-router-redux
.
import { push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
Если вы используете reducex thunk / saga для управления асинхронным потоком, импортируйте созданных выше создателей действий в действия redux и зацепите за взаимодействие с компонентами, используя mapDispatchToProps, возможно, лучше.
React-Router 4.0.0+ Answer
В 4.0 и выше используйте историю в качестве опоры вашего компонента.
class Example extends React.Component { // use `this.props.history.push('/some/path')` here };
React-Router 3.0.0+ Answer
В версии 3.0 и выше используйте маршрутизатор в качестве опоры вашего компонента.
class Example extends React.Component { // use `this.props.router.push('/some/path')` here };
React-Router 2.4.0+ Ответ
В 2.4 и выше используйте компонент более высокого порядка, чтобы получить маршрутизатор в качестве опоры вашего компонента.
import { withRouter } from 'react-router'; class Example extends React.Component { // use `this.props.router.push('/some/path')` here }; // Export the decorated class var DecoratedExample = withRouter(Example); // PropTypes Example.propTypes = { router: React.PropTypes.shape({ push: React.PropTypes.func.isRequired }).isRequired };
React-Router 2.0.0+ Answer
Эта версия обратно совместима с 1.x, поэтому нет необходимости в руководстве по обновлению.
При этом, если вы хотите переключиться на новый шаблон, внутри маршрутизатора есть браузерный модуль, к которому вы можете получить доступ с помощью
import { browserHistory } from 'react-router'
Теперь у вас есть доступ к истории вашего браузера, поэтому вы можете делать такие вещи, как push, replace и т. д. Например:
browserHistory.push('/some/path')
Дальнейшее чтение: Истории и Навигация
React-Router 1.xx Ответ
Я не буду вдаваться в подробности. Вы можете прочитать об этом в Руководстве по обновлению
. Основное изменение в вопросе здесь - это переход от навигационного микширования к истории. Теперь он использует историю браузераAPI для изменения маршрута, поэтому мы будем использовать
pushState()
с этого момента.Вот пример использования Mixin:
var Example = React.createClass({ mixins: [ History ], navigateToHelpPage () { this.history.pushState(null, `/help`); } })
Обратите внимание, что этот
History
приходит из rackt / history проект. Не из React-Router.Если вы не хотите использовать Mixin по какой-либо причине (возможно, из-за класса ES6), вы можете получить доступ к истории, которую вы получаете от маршрутизатора, с
this.props.history
, Он будет доступен только для компонентов, предоставляемых вашим маршрутизатором. Итак, если вы хотите использовать его в любых дочерних компонентах, его нужно передать в качестве атрибута черезprops
.Подробнее о новой версии вы можете прочитать в своей документации по 1.0.x
Вот справочная страница, в частности, о навигации вне вашего компонента
Он рекомендует захватить ссылку
history = createHistory()
и вызватьreplaceState
на это.React-Router 0.13.x Ответ
Я попал в ту же проблему и мог найти решение с помощью навигационного микшина, который приходит с реакцией [30]
import React from 'react'; import {Navigation} from 'react-router'; let Authentication = React.createClass({ mixins: [Navigation], handleClick(e) { e.preventDefault(); this.transitionTo('/'); }, render(){ return (<div onClick={this.handleClick}>Click me!</div>); } });
Мне удалось вызвать
transitionTo()
без необходимости доступа к.context
. Или вы может попробовать фантастический ES6
class
import React from 'react'; export default class Authentication extends React.Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick(e) { e.preventDefault(); this.context.router.transitionTo('/'); } render(){ return (<div onClick={this.handleClick}>Click me!</div>); } } Authentication.contextTypes = { router: React.PropTypes.func.isRequired };
React-Router-Redux
Примечание: если вы используете Redux, есть еще один проект под названием React-Router-Redux , который дает вам привязки редукции для ReactRouter, используя тот же подход, что React-Redux делает
React -Router-Redux имеет несколько доступных методов, которые позволяют просто перемещаться из создателей действий. Они могут быть особенно полезны для людей, имеющих существующую архитектуру в React Native, и они хотят использовать те же шаблоны в React Web с минимальными служебными надбавками.
Исследуйте следующие методы:
push(location)
replace(location)
go(number)
goBack()
goForward()
Ниже приведен пример использования с помощью Redux-Thunk :
./ actioncreators.js
import { goBack } from 'react-router-redux' export const onBackPress = () => (dispatch) => dispatch(goBack())
./ viewcomponent .js
<button disabled={submitting} className="cancel_button" onClick={(e) => { e.preventDefault() this.props.onBackPress() }} > CANCEL </button>
v2.4.0
, но упомянутый подход не работает для меня, мое приложение не отображает вообще, а выходы консоли: Uncaught TypeError: (0 , _reactRouter.withRouter) is not a function
вот ссылка на мою публикацию SO: stackoverflow.com/questions/ 37306166 / & hellip;
– nburk
18 May 2016 в 17:13
2.6.0
.
– JMac
23 July 2016 в 10:23
3.0.x
? Многие люди, кажется, используют путь context
.
– velop
5 December 2016 в 11:24
Если вы используете хэш или историю браузера, вы можете сделать
hashHistory.push('/login');
browserHistory.push('/login');
hashHistory.push
, дает Невозможно прочитать свойство & quot; push & quot; неопределенного. Откуда вы их импортируете?
– ArchNoob
6 September 2017 в 20:55
<Redirect>
. – Paul S 20 March 2017 в 18:15withRouter
вместо передачиhistory
вниз по всем моим компонентам? Gahh Мне нужно больше времени читать документы ... – hellojeffhall 22 July 2017 в 02:04Unexpected use of 'history' no-restricted-globals
– Pardeep Jain 3 October 2017 в 08:00