#reactjs #react-router
#reactjs #react-маршрутизатор
Вопрос:
Я использую react-route, и у меня возникли некоторые проблемы с маршрутизацией.
Перезагружается вся страница, в результате чего все данные, которые я уже извлек и сохранил в редукторе, загружаются каждый раз.
Вот мой файл маршрута :
var CustomRoute = React.createClass({
render:function(){
return <Router history={browserHistory}>
<Route path="/" component={Layout}>
<IndexRedirect to="/landing" />
<Route path="landing" component={Landing} />
<Route path="login" component={Login} />
<Route path="form" component={Form} />
<Route path="*" component={NoMatch} />
</Route>
</Router>
},
});
Перед маршрутизацией я уже сохраняю данные, вызывая action в моем main.jsx
/** @jsx React.DOM */
'use strict'
var ReactDOM = require('react-dom')
var React = require('react')
var Index = require('./components/index')
var createStore = require("redux").createStore
var applyMiddleware = require("redux").applyMiddleware
var Provider = require("react-redux").Provider
var thunkMiddleware = require("redux-thunk").default
var reducer = require("./reducers")
var injectTapEventPlugin =require('react-tap-event-plugin');
injectTapEventPlugin()
var createStoreWithMiddleware=applyMiddleware(thunkMiddleware)(createStore);
var store=createStoreWithMiddleware(reducer);
store.dispatch(actions.load_contacts()) //////////// <<<<<< this is what i call to store data already
ReactDOM.render( <Provider store={store}><Index/></Provider> , document.getElementById('content'))
Проблема в том, что мне нужно перенаправить на другую страницу, если успешный вход в систему :
this.props.dispatch(actions.login(this.state.login,this.state.password,(err)=>{
this.setState({err:err})
if (!err){
window.location = "/form"
}
}));
Окно.местоположение делает свое дело, но оно перезагружает все, что очень неэффективно.
В ручном маршруте я использую <Link>
эти маршруты без перезагрузки, однако для автоматического я не уверен, как это сделать.
Любое предложение будет высоко оценено.
Ответ №1:
для самой последней версии ( v2.0.0-rc5
) рекомендуемый метод навигации — прямое нажатие на синглтон истории.
Соответствующий код
import { browserHistory } from './react-router'
browserHistory.push('/some/path')
При использовании более нового API-интерфейса react-router вам необходимо использовать history
from this.props
when внутри компонентов, чтобы:
static propTypes = {
history: React.PropTypes.object
}
this.props.history.push('/some/path');
При использовании react-router-redux
он предлагает push
функцию, которую вы можете отправить следующим образом:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
В версии v2.4.0 и выше используйте компонент более высокого порядка, чтобы получить маршрутизатор в качестве опоры вашего компонента.
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
};
Посетите эту ссылку для получения дополнительной информации: http://kechengpuzi.com/q/s31079081
Комментарии:
1. Большое спасибо, это помогло мне. Просто импортируйте
var browserHistory = require('react-router').browserHistory
и вызывайтеbrowserHistory.push('/form')
.2. Я сделал это, и вся страница все еще обновляется
3. Ссылка на демонстрационный пример недоступна (404). Ссылка на дополнительную информацию также недоступна. Можете ли вы обновить этот ответ?
Ответ №2:
React> = 16.8 и react-router v4
Никто не упомянул решение для приложения, использующего хуки. Начиная с React 16.8 (и react-router 4, не уверен, какая минимальная версия, я использую последнюю), вы можете использовать перехват под названием useHistory .
import { useHistory } from 'react-router';
const MyHookComponent: React.FC = () => {
const routerHistory = useHistory();
routerHistory.push('/page-where-to-redirect');
return <></>;
}
export default MyHookComponent;
Подробнее здесь https://reactrouter.com/web/api/Hooks /.
Обновление: react-router v6
В react-router 6 появился новый хук:
import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
navigate('/page-where-to-redirect');
Документацию можно найти здесь https://reactrouterdotcom.fly.dev/docs/en/v6/api#usenavigate
Ответ №3:
Это единственное, что сработало для меня:
window.history.pushState("", "", "/new-url");
ИЛИ заменить:
window.history.replaceState("", "", "/new-url");
Ответ №4:
Сначала импортируйте компонент ссылки :
import { Link } from 'react-router-dom'
вместо :
<Route path="landing" component={Landing} />
используйте :
<Link to="landing" />
Комментарии:
1. Тогда как React-Bootstrap должен знать, показывать
Landing
ли страницу, если она даже не указана? Ссылка на «/ landing» или что-либо подобное не имеет смысла безRoute
компонента..
Ответ №5:
Ниже приведен пример конфигурации маршрутов, который я использовал в некоторых своих проектах, и он должен быть вам полезен:
import App from '../App';
import Home from '../components/pages/Home';
import Login from '../components/pages/Login';
import Register from '../components/pages/Register';
function shouldBeLoggedIn(nextState, replace) {
// const status = getLoginStatus(); //From the State manager
// if( status amp;amp; !status.loggedin ){
// replace({
// pathname: '/login',
// state: { nextPathname: nextState.location.pathname }
// })
// }
console.log('Should be Logged in!')
}
function shouldNotBeLoggedIn(nextState, replace) {
// const status = getLoginStatus();
// if( status amp;amp; status.loggedin ){
// replace({
// pathname: '/home',
// state: { nextPathname: nextState.location.pathname }
// })
// }
console.log('Should Not be Logged in!')
}
const rootRoute = {
path: '/',
component: App,
indexRoute: {
component: Login,
onEnter: shouldNotBeLoggedIn
},
indexRedirect: {
to: '/'
},
childRoutes: [ {
path: 'home',
component: Home,
onEnter: shouldBeLoggedIn
}, {
path: 'login',
component: Login,
onEnter: shouldNotBeLoggedIn
}, {
path: 'register',
component: Register,
onEnter: shouldNotBeLoggedIn
}
]
}
export default rootRoute;
В приведенном выше коде каждый маршрут имеет привязку onEnter к методам жизненного цикла маршрутизатора, которые будут решать, следует ли вводить маршрут или нет. И если вы посмотрите на комментарий, вы можете решить, что делать в подключенном методе.
Вы можете просмотреть приведенный выше код в следующем репозитории github: http://github.com/pankajpatel/kickstart-react и файл в https://github.com/pankajpatel/kickstart-react/blob/master/src/js/routes/routes.js
Ниже приведен пример из документации API для react-router:
const userIsInATeam = (nextState, replace, callback) => {
fetch(...)
.then(response = response.json())
.then(userTeams => {
if (userTeams.length === 0) {
replace(`/users/${nextState.params.userId}/teams/new`)
}
callback();
})
.catch(error => {
// do some error handling here
callback(error);
})
}
<Route path="/users/:userId/teams" onEnter={userIsInATeam} />
Ответ №6:
React Router v4 — компонент перенаправления
Рекомендуемый способ react-router v4 — разрешить вашему методу рендеринга перехватывать перенаправление. Используйте state или props, чтобы определить, нужно ли показывать компонент перенаправления.
Ссылка : https://reacttraining.com/react-router/web/api/Redirect
-
Импортируйте
Redirect
изreact-router
.import { Redirect } from 'react-router';
-
Определите событие щелчка, чтобы изменить состояние.
handleOnClick = () => { // redirect this.setState({redirect: true}); }
-
Измените метод визуализации, например,
render() { if (this.state.redirect) { return <Redirect push to="/yourpath" />; } return ( <button onClick={this.handleOnClick} type="button">Button</button> ); }
-
Пример кода :
import { Redirect } from 'react-router'; //import Redirect export default class ConfirmationDialog extends Component{ constructor(props) { super(props); //init the state this.state = { redirect : false } } handleOnClick = () => { //set the redirect property to true for allow redirect this.setState({redirect: true}); } render() { //check if the redirec is allowed if (this.state.redirect) { return <Redirect push to="/yourpath" />; } //if not put your code here return ( //your code <button onClick={this.handleOnClick} type="button">Button</button> ); } }
-