Как использовать Redirect в новом реале-маршрутизаторе Reactjs
Я использую модуль реакции-маршрутизатора последней версии, названный реагировать-маршрутизатор-дом, который стал по умолчанию при разработке веб-приложений с React. Я хочу знать, как сделать перенаправление после запроса POST. Я делал этот код, но после запроса ничего не происходит. Я просматриваю в Интернете, но все данные о предыдущих версиях реагирующего маршрутизатора, а не о последнем обновлении.
Код:
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Redirect } from 'react-router'
import SignUpForm from '../../register/components/SignUpForm';
import styles from './PagesStyles.css';
import axios from 'axios';
import Footer from '../../shared/components/Footer';
class SignUpPage extends React.Component {
constructor(props) {
super(props);
this.state = {
errors: {},
client: {
userclient: '',
clientname: '',
clientbusinessname: '',
password: '',
confirmPassword: ''
}
};
this.processForm = this.processForm.bind(this);
this.changeClient = this.changeClient.bind(this);
}
changeClient(event) {
const field = event.target.name;
const client = this.state.client;
client[field] = event.target.value;
this.setState({
client
});
}
async processForm(event) {
event.preventDefault();
const userclient = this.state.client.userclient;
const clientname = this.state.client.clientname;
const clientbusinessname = this.state.client.clientbusinessname;
const password = this.state.client.password;
const confirmPassword = this.state.client.confirmPassword;
const formData = { userclient, clientname, clientbusinessname, password, confirmPassword };
axios.post('/signup', formData, { headers: {'Accept': 'application/json'} })
.then((response) => {
this.setState({
errors: {}
});
<Redirect to="/"/> // Here, nothings happens
}).catch((error) => {
const errors = error.response.data.errors ? error.response.data.errors : {};
errors.summary = error.response.data.message;
this.setState({
errors
});
});
}
render() {
return (
<div className={styles.section}>
<div className={styles.container}>
<img src={require('./images/lisa_principal_bg.png')} className={styles.fullImageBackground} />
<SignUpForm
onSubmit={this.processForm}
onChange={this.changeClient}
errors={this.state.errors}
client={this.state.client}
/>
<Footer />
</div>
</div>
);
}
}
export default SignUpPage;
Ответы
Ответ 1
Вы должны использовать setState
чтобы установить свойство, которое будет отображать <Redirect>
внутри вашего метода render()
.
Например
class MyComponent extends React.Component {
state = {
redirect: false
}
handleSubmit () {
axios.post(/**/)
.then(() => this.setState({ redirect: true }));
}
render () {
const { redirect } = this.state;
if (redirect) {
return <Redirect to='/somewhere'/>;
}
return <RenderYourForm/>;
}
Вы также можете увидеть пример в официальной документации: https://reacttraining.com/react-router/web/example/auth-workflow
Тем не менее, я бы посоветовал вам поместить вызов API в сервис или что-то в этом роде. Тогда вы можете просто использовать объект history
для программной маршрутизации. Вот как работает интеграция с Redux.
Но я думаю, у тебя есть причины сделать это таким образом.
Ответ 2
Вот небольшой пример в ответ на название, так как все упомянутые примеры сложны, на мой взгляд, так же, как и официальный.
Вы должны знать, как переносить es2015, а также чтобы ваш сервер мог обрабатывать перенаправление. Вот фрагмент для экспресса. Дополнительную информацию, связанную с этим, можно найти здесь.
Не забудьте указать это ниже всех других маршрутов.
const app = express();
app.use(express.static('distApp'));
/**
* Enable routing with React.
*/
app.get('*', (req, res) => {
res.sendFile(path.resolve('distApp', 'index.html'));
});
Это файл .jsx. Обратите внимание, что самый длинный путь идет первым и становится более общим. Для наиболее общих маршрутов используйте точный атрибут.
// Relative imports
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
// Absolute imports
import YourReactComp from './YourReactComp.jsx';
const root = document.getElementById('root');
const MainPage= () => (
<div>Main Page</div>
);
const EditPage= () => (
<div>Edit Page</div>
);
const NoMatch = () => (
<p>No Match</p>
);
const RoutedApp = () => (
<BrowserRouter >
<Switch>
<Route path="/items/:id" component={EditPage} />
<Route exact path="/items" component={MainPage} />
<Route path="/yourReactComp" component={YourReactComp} />
<Route exact path="/" render={() => (<Redirect to="/items" />)} />
<Route path="*" component={NoMatch} />
</Switch>
</BrowserRouter>
);
ReactDOM.render(<RoutedApp />, root);
Ответ 3
Просто вызовите его внутри любой функции, которая вам нравится.
this.props.history.push('/main');
Ответ 4
Попробуйте что-нибудь подобное.
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Redirect } from 'react-router'
import SignUpForm from '../../register/components/SignUpForm';
import styles from './PagesStyles.css';
import axios from 'axios';
import Footer from '../../shared/components/Footer';
class SignUpPage extends React.Component {
constructor(props) {
super(props);
this.state = {
errors: {},
callbackResponse: null,
client: {
userclient: '',
clientname: '',
clientbusinessname: '',
password: '',
confirmPassword: ''
}
};
this.processForm = this.processForm.bind(this);
this.changeClient = this.changeClient.bind(this);
}
changeClient(event) {
const field = event.target.name;
const client = this.state.client;
client[field] = event.target.value;
this.setState({
client
});
}
processForm(event) {
event.preventDefault();
const userclient = this.state.client.userclient;
const clientname = this.state.client.clientname;
const clientbusinessname = this.state.client.clientbusinessname;
const password = this.state.client.password;
const confirmPassword = this.state.client.confirmPassword;
const formData = { userclient, clientname, clientbusinessname, password, confirmPassword };
axios.post('/signup', formData, { headers: {'Accept': 'application/json'} })
.then((response) => {
this.setState({
callbackResponse: {response.data},
});
}).catch((error) => {
const errors = error.response.data.errors ? error.response.data.errors : {};
errors.summary = error.response.data.message;
this.setState({
errors
});
});
}
const renderMe = ()=>{
return(
this.state.callbackResponse
? <SignUpForm
onSubmit={this.processForm}
onChange={this.changeClient}
errors={this.state.errors}
client={this.state.client}
/>
: <Redirect to="/"/>
)}
render() {
return (
<div className={styles.section}>
<div className={styles.container}>
<img src={require('./images/lisa_principal_bg.png')} className={styles.fullImageBackground} />
{renderMe()}
<Footer />
</div>
</div>
);
}
}
export default SignUpPage;
Ответ 5
В качестве альтернативы вы можете использовать withRouter
. Вы можете получить доступ к свойствам объекта history
и ближайшим <Route>
match
через компонент высшего порядка withRouter
. withRouter
будет передавать обновленные реквизиты match
, location
и history
в обернутый компонент всякий раз, когда он рендерится.
import React from "react"
import PropTypes from "prop-types"
import { withRouter } from "react-router"
// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
}
render() {
const { match, location, history } = this.props
return <div>You are now at {location.pathname}</div>
}
}
// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)
Или просто:
import { withRouter } from 'react-router-dom'
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
Ответ 6
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-router-dom": "^4.2.2"
Для перехода на другую страницу (о странице в моем случае) я установил prop-types
. Затем я импортирую его в соответствующий компонент. И я использовал this.context.router.history.push('/about')
. И он перемещается.
Мой код
import React, { Component } from 'react';
import '../assets/mystyle.css';
import { Redirect } from 'react-router';
import PropTypes from 'prop-types';
export default class Header extends Component {
viewAbout() {
this.context.router.history.push('/about')
}
render() {
return (
<header className="App-header">
<div className="myapp_menu">
<input type="button" value="Home" />
<input type="button" value="Services" />
<input type="button" value="Contact" />
<input type="button" value="About" onClick={() => { this.viewAbout() }} />
</div>
</header>
)
}
}
Header.contextTypes = {
router: PropTypes.object
};
Ответ 7
Для перехода к другому компоненту вы можете использовать this.props.history.push('/main');
import React, { Component, Fragment } from 'react'
class Example extends Component {
redirect() {
this.props.history.push('/main')
}
render() {
return (
<Fragment>
{this.redirect()}
</Fragment>
);
}
}
export default Example
Ответ 8
Вы можете написать hoc для этой цели и написать перенаправление вызова метода, вот код:
import React, {useState} from 'react';
import {Redirect} from "react-router-dom";
const RedirectHoc = (WrappedComponent) => () => {
const [routName, setRoutName] = useState("");
const redirect = (to) => {
setRoutName(to);
};
if (routName) {
return <Redirect to={"/" + routName}/>
}
return (
<>
<WrappedComponent redirect={redirect}/>
</>
);
};
export default RedirectHoc;
Ответ 9
Самым простым решением для перехода к другому компоненту является (например, переход к компоненту почты с помощью значка):
<MailIcon
onClick={ () => { this.props.history.push('/mails') } }
/>
Ответ 10
Кроме того, вы можете использовать условный рендеринг React.
import { Redirect } from "react-router";
import React, { Component } from 'react';
class UserSignup extends Component {
constructor(props) {
super(props);
this.state = {
redirect: false
}
}
render() {
<React.Fragment>
{ this.state.redirect && <Redirect to="/signin" /> } // you will be redirected to signin route
}
</React.Fragment>
}
Ответ 11
React Router v5 теперь позволяет вам просто перенаправлять с помощью history.push() благодаря хуку useHistory():
import { useHistory } from "react-router"
function HomeButton() {
let history = useHistory()
function handleClick() {
history.push("/home")
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
)
}
Ответ 12
Я попробовал простой взлом. Может не хорошо, но это работает для меня. Я написал этот простой код внутри событий. Это перенаправит на конкретное местоположение браузера (/path
)
handleSubmit () {
axios.post(/**/)
.then(() => {
this.setState({ redirect: true }));
window.location.href='/path';
}
}