קורס React 2020 שיעור שינוי נתיב יזום עם אלמנט Redirect


זהו נושא דיון מלווה לערך המקורי שב־https://www.tocode.co.il/bundles/react/lessons/redirect

שלום,
רציתי לשאול, כיצד הכי נכון להוסיף לתרגיל הטפסים את ריאקט ראוטר?
ניסיתי להוסיף את הראוטר רק שאני לא מצליחה להשאיר את הקוד גנרי כמו שהיה קודם כיון שכל עמוד שארצה להוסיף לטופס לא מספיק שאוסיף אותו בתור ילד למיכל של הטפסים אלא אצטרך גם ב-main.js להוסיף את ה-Route המתאים וגם לטפל במשתנה pages שבתוך הקומפוננטה FormsContainer, אשמח אם תוכל לכוון אותי לקוד יותר גנרי:
main.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { BrowserRouter as Router , Route , Redirect , Switch} from 'react-router-dom';

import store from './redux/store';
import FormsApp from './formsApp';
import '../style/main.scss';

const App = () => {

    return (
        <Provider store = {store}>
            <Router>
                <Switch>
                    <Route path="/loginPage" component = {()=><FormsApp currentFormIndex = {0}/>}/>
                    <Route path="/countryAndCitySelection"  component = {()=><FormsApp currentFormIndex = {1}/>}/>
                    <Route path="/hobbiesSelection"  component = {()=><FormsApp currentFormIndex = {2}/>}/>
                    <Route path="/summaryPage"  component = {()=><FormsApp currentFormIndex = {3}/>}/>
                    <Redirect from="/" to ="/loginPage"/>
                </Switch>
            </Router>
        </Provider>
    );
};

ReactDOM.render(<App/> , document.querySelector('main'));

formsApp.js


import FormsContainer from './formsContainer';
import LoginPage from './loginPage';
import CountryAndCitySelection from './countryAndCitySelection';
import HobbiesSelection from './hobbiesSelection';
import SummaryPage from './summaryPage';

export default function FormsApp(props) {

    return (
        <FormsContainer {...props}>
            <LoginPage/>
            <CountryAndCitySelection/>
            <HobbiesSelection/>
            <SummaryPage/>
        </FormsContainer>
    );
}

formsContainer.js

import React from 'react' ;
import { withRouter } from 'react-router-dom';

import UndoRedo from './undoRedo';

export default withRouter(function FormsContainer(props) {
    const { currentFormIndex , history} = props;
    const countOfPages = React.Children.count(props.children);
    
    const pages = {
        0: "/loginPage",
        1: "/countryAndCitySelection",
        2: "/hobbiesSelection",
        3: "/summaryPage",
    }

    function previousBtnClick() {
        history.push(pages[currentFormIndex - 1]);
    }

    function nextBtnClick() {
        history.push(pages[currentFormIndex + 1]);
    }

    return (
        <div className="divContainerForm">
            <UndoRedo/>
            {props.children[currentFormIndex]}
            <div className="btnsContainer">
                <button className="btn btn-lg btn-primary" onClick={previousBtnClick} disabled={currentFormIndex===0}>Previous</button>
                <button className="btn btn-lg btn-primary" onClick={nextBtnClick} disabled={currentFormIndex===countOfPages-1}>Next</button>
            </div>
        </div>
    );
});

הגרסה הקודמת של פקד המיכל בלי הראוטר:

import React from 'react' ;
import { connect } from 'react-redux';

import UndoRedo from './undoRedo';
import { previousBtnClick , nextBtnClick } from './redux/actions';

function mapStateToProps(state) {
    return {
        currentFormIndex: state.router.currentFormIndex,
    };
}

export default connect(mapStateToProps)(function FormsContainer(props) {
    const { currentFormIndex , dispatch} = props;
    const countOfPages = React.Children.count(props.children);

    return (
        <div className="divContainerForm">
            <UndoRedo/>
            {props.children[currentFormIndex]}
            <div className="btnsContainer">
                <button className="btn btn-lg btn-primary" onClick={()=>dispatch(previousBtnClick())} disabled={currentFormIndex===0}>Previous</button>
                <button className="btn btn-lg btn-primary" onClick={()=>dispatch(nextBtnClick())} disabled={currentFormIndex===countOfPages-1}>Next</button>
            </div>
        </div>
    );
});

נכון אז השאלה כאן מה יהיה מבנה ה URL-ים ואיך החיבור הגנרי הולך להיעשות. מצד שני לא חייבים שכל דף בטופס יהיה ב Route נפרד. אפשר להשתמש ב URL Parameter ולבנות סכימה עם הנתיבים:

/form?page=login
/form?page=address
/form?page=hobbies
/form?page=summary

במצב כזה יהיה לך רק Route אחד והקומפוננטה תוכל למשוך את ערך הפרמטר ולהציג את הדף המתאים. יותר מזה, בגלל ש React Router תומך בפרמטרים כחלק מהנתיב אפשר יהיה להשתמש במבנה הבא:

/form/:page

ואז לקבל:

/form/login
/form/hobbies
/form/summary

וכך הלאה.

לייק 1