Reactjs के नए प्रतिक्रिया-राउटर-डोम में रीडायरेक्ट का उपयोग कैसे करें


131

मैं अंतिम संस्करण प्रतिक्रिया-राउटर मॉड्यूल का उपयोग कर रहा हूं, जिसका नाम प्रतिक्रिया-राउटर-डोम है, जो रिएक्ट के साथ वेब एप्लिकेशन विकसित करते समय डिफ़ॉल्ट हो गया है। मैं जानना चाहता हूं कि पोस्ट अनुरोध के बाद पुनर्निर्देशन कैसे किया जाए। मैं यह कोड बना रहा हूं, लेकिन अनुरोध के बाद भी कुछ नहीं होता है। मैं वेब पर समीक्षा करता हूं, लेकिन सभी डेटा प्रतिक्रिया रूटर के पिछले संस्करणों के बारे में हैं, और अंतिम अपडेट के साथ नहीं।

कोड:

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
आपका Redirectलुक JSX जैसा है, JS नहीं।
एलमिस्टर

क्या आप आपको पूरा घटक कोड प्रदान कर सकते हैं
KornholioBeavis

हां, मैं JSX का उपयोग कर रहा हूं। खैर, शायद मुझे स्पष्ट करने की आवश्यकता है। POST अनुरोध REACT घटक के अंदर है जो अनुरोध करता है।
moorooricio

@KornholioBeavis, निश्चित रूप से, अब आप पूरा देख सकते हैं। मैं एक्सप्रेस के साथ सर्वर बनाता हूं, मुझे नहीं पता कि आपको इस डेटा की आवश्यकता है
mauooricio

क्या आप मान्य कर सकते हैं कि आपको axios.post से कॉलबैक प्रतिक्रिया मिल रही है? इसके अलावा आप कहीं भी इंतजार किए बिना async फ़ंक्शन का उपयोग क्यों कर रहे हैं?
KornholioBeavis

जवाबों:


197

आपको 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


उस ने कहा, मैं आपको सुझाव दूंगा कि आप एपीआई कॉल को किसी सेवा या किसी चीज़ के अंदर रखें। तब आप historyप्रोग्राम को रूट करने के लिए ऑब्जेक्ट का उपयोग कर सकते हैं । यह कैसे Redux काम करता है के साथ एकीकरण है

लेकिन मुझे लगता है कि आपके पास इसे करने के लिए आपके कारण हैं।


1
@sebastian sebald से आपका क्या तात्पर्य है put the API call inside a service or something:?
andrea-f

1
आपके घटक के अंदर इस तरह की (async) एपीआई कॉल होने से परीक्षण और पुन: उपयोग करना कठिन हो जाएगा। यह आमतौर पर एक सेवा बनाने के लिए बेहतर है और फिर (उदाहरण के लिए) में इसका उपयोग करें componentDidMount। या इससे भी बेहतर, एक ऐसा HOC बनाएं जो आपके API को "लपेटे"।
सेबस्टियन सेबल

6
ध्यान दें कि आपको फ़ाइल की शुरुआत में इसका उपयोग करने के लिए रीडायरेक्ट को शामिल करना होगा: 'रिएक्टर-राउटर-डोम' से {Redirect} आयात करें
एलेक्स

3
हाँ, हुड के तहत Redirectबुला रहा है history.replace। यदि आप historyआज्ञाचक्र का उपयोग करना चाहते हैं , तो withRoutet/ का उपयोग करें Route
सेबस्टियन सेबाल

1
react-router> = ५.१ में अब हुक शामिल हैं, इसलिए आप बसconst history = useHistory(); history.push("/myRoute")
TheDarkIn1978

34

यहाँ शीर्षक के जवाब के रूप में एक छोटा सा उदाहरण के रूप में सभी उल्लेख उदाहरण मेरी राय के साथ ही आधिकारिक एक में जटिल हैं।

आपको पता होना चाहिए कि 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); 

1
यह हर समय काम नहीं करता है। यदि आपके पास home/hello> से पुनर्निर्देशित है, home/hello/1लेकिन तब जाकर home/helloपहली बार अनुप्रेषित में प्रवेश करें। किसी भी विचार क्यों ??
वालरस

मैं आपको सलाह देता हूं कि यदि संभव हो तो "create-react-app" का उपयोग करें और प्रतिक्रिया-राउटर से प्रलेखन का पालन करें। "क्रिएट-रिएक्शन-ऐप" के साथ मेरे लिए सब कुछ ठीक काम करता है। मैं नए प्रतिक्रिया-राउटर के लिए अपने स्वयं के प्रतिक्रिया एप्लिकेशन को अनुकूलित करने में सक्षम नहीं था।
मथिस कोहली


8

React Router v5 अब आपको हिस्ट्री.पश () का उपयोग कर अप्रत्यक्ष करने की अनुमति देता है। उपयोग के लिए धन्यवाद () हुक :

import { useHistory } from "react-router"

function HomeButton() {
  let history = useHistory()

  function handleClick() {
    history.push("/home")
  }

  return (
    <button type="button" onClick={handleClick}>
      Go home
    </button>
  )
}

6

कुछ इस तरह की कोशिश करो।

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;

यह काम करता है !, आपको बहुत धन्यवाद। यह ऐसा करने का एक और तरीका है।
मओउरीसीओ

आपको अपनी घटक फाइलों में HTTP अनुरोध नहीं करना चाहिए
Kermit_ice_tea

क्या आप '..///register/compords/SignUFF'' से साइनअप आयात के अंदर क्या साझा कर सकते हैं? मैं इससे सीखने की कोशिश कर रहा हूं। हालांकि मेरे मामले में, मैं
टेमी 'टॉपसी' बेलो

3

वैकल्पिक रूप से, आप उपयोग कर सकते हैं 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>
))

1

आप इस उद्देश्य के लिए एक हॉक लिख सकते हैं और एक विधि कॉल रीडायरेक्ट लिख सकते हैं, यहां कोड है:

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;

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

0

दूसरे घटक पर नेविगेट करने के लिए जिसका आप उपयोग कर सकते हैं 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

1
रिएक्ट एक चेतावनी फेंकता है: Warning: Cannot update during an existing state transition (such as within रेंडर). Render methods should be a pure function of props and state.
रोबोटॉन

0

किसी अन्य घटक पर नेविगेट करने का सबसे सरल उपाय है (उदाहरण आइकन पर क्लिक करके मेल को घटक को नेविगेट करता है):

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

0

वैकल्पिक रूप से, आप रिएक्ट सशर्त प्रतिपादन का उपयोग कर सकते हैं।

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>
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.