Hoe Redirect te gebruiken in de nieuwe react-router-dom van Reactjs

Ik gebruik de laatste versie van de react-router-module, genaamd react-router-dom, die de standaard is geworden bij het ontwikkelen van webapplicaties met React. Ik wil weten hoe ik een omleiding kan maken na een POST-verzoek. Ik heb deze code gemaakt, maar na het verzoek gebeurt er niets. Ik review op internet, maar alle gegevens gaan over eerdere versies van de react-router en niet over de laatste update.

Code:

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;

Antwoord 1, autoriteit 100%

U moet setStategebruiken om een eigenschap in te stellen die de <Redirect>binnen uw render()-methode weergeeft.

Bijvoorbeeld

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/>;
}

Je kunt ook een voorbeeld zien in de officiële documentatie: https://reacttraining .com/react-router/web/example/auth-workflow


Dat gezegd hebbende, raad ik je aan om de API-aanroep in een service of zoiets te plaatsen. Dan zou je gewoon het historyobject kunnen gebruiken om programmatisch te routeren. Dit is hoe de integratie met redux werkt.

Maar ik denk dat je je redenen hebt om het op deze manier te doen.


Antwoord 2, autoriteit 18%

Hier een klein voorbeeld als reactie op de titel, aangezien alle genoemde voorbeelden naar mijn mening ingewikkeld zijn, evenals de officiële.

U moet weten hoe u es2015 moet transpileren en hoe u uw server in staat moet stellen om de omleiding te verwerken. Hier is een fragment voor express. Meer informatie hierover is te vinden hier.

Zorg ervoor dat u dit onder alle andere routes plaatst.

const app = express();
app.use(express.static('distApp'));
/**
 * Enable routing with React.
 */
app.get('*', (req, res) => {
  res.sendFile(path.resolve('distApp', 'index.html'));
});

Dit is het .jsx-bestand. Merk op hoe het langste pad eerst komt en algemener wordt. Gebruik voor de meest algemene routes het exacte kenmerk.

// 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); 

Antwoord 3, autoriteit 13%

React Router v5 stelt je nu in staat om eenvoudig om te leiden met history.push() dankzij de useHistory() hook:

import { useHistory } from "react-router-dom"
function HomeButton() {
  let history = useHistory()
  function handleClick() {
    history.push("/home")
  }
  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  )
}

Antwoord 4, autoriteit 9%

Noem het gewoon in elke gewenste functie.

this.props.history.push('/main');

Antwoord 5, autoriteit 3%

Probeer zoiets als dit.

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;

Antwoord 6

U kunt ook gebruik maken van withRouter. U kunt toegang krijgen tot de eigenschappen van het historyobjecten en de dichtstbijzijnde <Route>‘s matchvia de withRouterhogere orde component. withRouterWordt bijgewerkt match, location, en historyRekwisies aan de gewikkelde component wanneer deze zich maakt.

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)

of alleen:

import { withRouter } from 'react-router-dom'
const Button = withRouter(({ history }) => (
  <button
    type='button'
    onClick={() => { history.push('/new-location') }}
  >
    Click Me!
  </button>
))

Antwoord 7

Het probleem dat ik tegenkom is dat ik een bestaande IIS-machine heb. Ik implementeer er vervolgens een statische React-app op. Wanneer u een router gebruikt, is de weergegeven URL eigenlijk virtueel, niet echt. Als u op F5 drukt, gaat het naar IIS, niet naar index.js, en uw terugkeer is 404-bestand niet gevonden. Hoe ik het heb opgelost was simpel. Ik heb een openbare map in mijn reactie-app. In die openbare map heb ik dezelfde mapnaam gemaakt als de virtuele routering. In deze map heb ik een index.html met de volgende code:

<script>
  {
    localStorage.setItem("redirect", "/ansible/");
    location.href = "/";
  }
</script>

Wat dit doet is voor deze sessie, ik voeg het “routing”-pad toe dat ik wil dat het gaat. Dan doe ik dit in mijn App.js (Let op … is andere code, maar te veel om hier te plaatsen voor een demo):

import React, { Component } from "react";
import { Route, Link } from "react-router-dom";
import { BrowserRouter as Router } from "react-router-dom";
import { Redirect } from 'react-router';
import Ansible from "./Development/Ansible";
import Code from "./Development/Code";
import Wood from "./WoodWorking";
import "./App.css";
class App extends Component {
  render() {
    const redirect = localStorage.getItem("redirect");
    if(redirect) {
      localStorage.removeItem("redirect");
    }
    return (
      <Router>
        {redirect ?<Redirect to={redirect}/> : ""}
        <div className="App">
        ...
          <Link to="/">
            <li>Home</li>
          </Link>
          <Link to="/dev">
            <li>Development</li>
          </Link>
          <Link to="/wood">
            <li>Wood Working</li>
          </Link>
        ...
          <Route
            path="/"
            exact
            render={(props) => (
              <Home {...props} />
            )}
          />
          <Route
            path="/dev"
            render={(props) => (
              <Code {...props} />
            )}
          />
          <Route
            path="/wood"
            render={(props) => (
              <Wood {...props} />
            )}
          />
          <Route
            path="/ansible/"
            exact
            render={(props) => (
              <Ansible {...props} checked={this.state.checked} />
            )}
          />
          ...
      </Router>
    );
  }
}
export default App;

Werkelijk gebruik: chizl.com


Antwoord 8

je kunt hiervoor een hoc schrijven en een method call redirect schrijven, hier is de code:

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;

Antwoord 9

De eenvoudigste oplossing om naar een andere component te navigeren (voorbeeld
Navigeert naar Mails Component door op Pictogram te klikken):

<MailIcon 
  onClick={ () => { this.props.history.push('/mails') } }
/>

Antwoord 10

"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-router-dom": "^4.2.2"

Voor navigeer naar een andere pagina (over pagina in mijn geval), heb ik prop-typesgeïnstalleerd. Dan importeer ik het in de bijbehorende component. En ik gebruikte this.context.router.history.push('/about'). En het wordt geavigeerd.

Mijn code is,

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
  };

Antwoord 11

Om naar een andere component te navigeren, kunt u 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

Antwoord 12

Als alternatief kunt u React voorwaardelijke weergave gebruiken.

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>
}

Antwoord 13

Ik heb gevonden dat de plaats om de omleidingscomplement van react-router te plaatsen in de methode render is, maar als je bijvoorbeeld na enige validatie wilt omleiden, is de beste manier om om te leiden het gebruik van de oude betrouwbare, window.location. href, dat wil zeggen:

evalSuccessResponse(data){
   if(data.code===200){
    window.location.href = urlOneSignHome;
   }else{
     //TODO Something
   }    
}

Als je programmeert, hoeft React Native nooit buiten de app te gaan, en het mechanisme om een andere app te openen is compleet anders.


Antwoord 14

Hallo als je react-router v-6.0.0-beta of V6 gebruikt in deze versie Stuur wijzigingen om om op deze manier te navigeren

importeer { Navigeer } van ‘react-router-dom’; // vind dit JUIST in v6
importeer { Redirect } van ‘react-router-dom’; // vind dit JUIST in v5

importeer { Redirect } van ‘react-router-dom’; // zoals dit FOUT in v6
// Dit geeft je een foutmelding in V6 van react-router en react-router dom

Zorg ervoor dat u beide dezelfde versie gebruikt in package.json
{
“react-router”: “^6.0.0-beta.0”, //Zoals dit
“react-router-dom”: “^6.0.0-beta.0”, // zoals dit
}

deze bovenstaande dingen werken alleen goed in react Router Versie 6

Other episodes