ค้นหาเว็บไซต์

javascript - วิธีใช้ Redirect ในเวอร์ชัน 5 ของ react-router-dom ของ Reactjs


ฉันกำลังใช้โมดูล react-router เวอร์ชันล่าสุด ที่ชื่อว่า react-router-dom ซึ่งกลายเป็นค่าเริ่มต้นเมื่อพัฒนาเว็บแอปพลิเคชันด้วย React ฉันต้องการรู้วิธีทำการเปลี่ยนเส้นทางหลังจากคำขอ POST ฉันได้เขียนโค้ดนี้แล้ว แต่หลังจากส่งคำขอแล้ว ไม่เกิดอะไรขึ้น ฉันได้ตรวจสอบบนเว็บ แต่ข้อมูลทั้งหมดเกี่ยวกับเวอร์ชันก่อนหน้าของ react-router และไม่มีข้อมูลเกี่ยวกับการอัปเดตล่าสุด

รหัส :

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 รวมถึงทำให้เซิร์ฟเวอร์ของคุณสามารถจัดการกับการเปลี่ยนเส้นทางได้ นี่คือตัวอย่างสั้น ๆ สำหรับ express ข้อมูลเพิ่มเติมที่เกี่ยวข้องกับเรื่องนี้สามารถพบได้ที่นี่

ตรวจสอบให้แน่ใจว่าวางสิ่งนี้ไว้ใต้เส้นทางอื่นทั้งหมด

const app = express();
app.use(express.static('distApp'));

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

นี่คือไฟล์ .jsx สังเกตว่าพาธที่ยาวที่สุดอยู่ก่อนและจะเริ่มกว้างขึ้น สำหรับเส้นทางที่กว้างที่สุดให้ใช้แอตทริบิวต์ exact

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

React Router v5 ตอนนี้อนุญาตให้คุณทำการเปลี่ยนเส้นทางได้ง่าย ๆ โดยใช้ history.push() ขอบคุณฟังก์ชัน 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>
  )
}

คำตอบ #4

เพียงแค่เรียกใช้มันภายในฟังก์ชันใดก็ได้ที่คุณต้องการ

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

บทความที่เกี่ยวข้อง