Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to use react-router-dom in scratch-gui? If so, how can I do it? #9707

Open
aquino-luane opened this issue Oct 22, 2024 · 6 comments

Comments

@aquino-luane
Copy link

I am trying to integrate react-router-dom into the scratch-gui mod project to handle routing. I attempted to configure the router in the app-state-hoc.jsx file, but it did not work as expected. Here is the code I tried:

import {
    BrowserRouter as Router,
    Switch,
    Route
} from 'react-router-dom';
....
render () {
            const {
                isFullScreen, // eslint-disable-line no-unused-vars
                isPlayerOnly, // eslint-disable-line no-unused-vars
                isTelemetryEnabled, // eslint-disable-line no-unused-vars
                showTelemetryModal, // eslint-disable-line no-unused-vars
                ...componentProps
            } = this.props;
            return (
                <Provider store={this.store}>
                    <ConnectedIntlProvider>
                        <Router>
                            <Switch>
                                {/* Use variable studioPath to support /studio-playground/ or future route */}
                                <Route path="/">
                                    <WrappedComponent
                                        {...componentProps}
                                    />
                                </Route>
                            </Switch>
                        </Router>
                    </ConnectedIntlProvider>
                </Provider>
            );
        }
...

When I run the application, I get the following warning:

app-state-hoc.jsx:110 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Any help or guidance would be greatly appreciated.

@Tom-cy
Copy link

Tom-cy commented Oct 28, 2024

render-gui.jsx

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

import AppStateHOC from '../lib/app-state-hoc.jsx';
import GUI from '../containers/gui.jsx';
import HashParserHOC from '../lib/hash-parser-hoc.jsx';
import log from '../lib/log.js';

const onClickLogo = () => {
window.location = '#';
};

const handleTelemetryModalCancel = () => {
log('User canceled telemetry modal');
};

const handleTelemetryModalOptIn = () => {
log('User opted into telemetry');
};

const handleTelemetryModalOptOut = () => {
log('User opted out of telemetry');
};

export default (appTarget) => {
GUI.setAppElement(appTarget);

const WrappedGui = compose(AppStateHOC, HashParserHOC)(GUI);

const backpackHostMatches = window.location.href.match(
/[?&]backpack_host=([^&]*)&?/
);
const backpackHost = backpackHostMatches ? backpackHostMatches[1] : null;

const scratchDesktopMatches = window.location.href.match(
/[?&]isScratchDesktop=([^&]+)/
);
let simulateScratchDesktop;
if (scratchDesktopMatches) {
try {
simulateScratchDesktop = JSON.parse(scratchDesktopMatches[1]);
} catch {
simulateScratchDesktop = scratchDesktopMatches[1];
}
}

if (process.env.NODE_ENV === 'production' && typeof window === 'object') {
window.onbeforeunload = () => true;
}

ReactDOM.render(



{simulateScratchDesktop ? (

) : (

)}


,
appTarget
);
};

我昨天做的。

@Tom-cy
Copy link

Tom-cy commented Oct 28, 2024

and u can use "react-router-dom": "^5.3.4",

@aquino-luane
Copy link
Author

aquino-luane commented Oct 28, 2024

render-gui.jsx

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

import AppStateHOC from '../lib/app-state-hoc.jsx'; import GUI from '../containers/gui.jsx'; import HashParserHOC from '../lib/hash-parser-hoc.jsx'; import log from '../lib/log.js';

const onClickLogo = () => { window.location = '#'; };

const handleTelemetryModalCancel = () => { log('User canceled telemetry modal'); };

const handleTelemetryModalOptIn = () => { log('User opted into telemetry'); };

const handleTelemetryModalOptOut = () => { log('User opted out of telemetry'); };

export default (appTarget) => { GUI.setAppElement(appTarget);

const WrappedGui = compose(AppStateHOC, HashParserHOC)(GUI);

const backpackHostMatches = window.location.href.match( /[?&]backpack_host=([^&]*)&?/ ); const backpackHost = backpackHostMatches ? backpackHostMatches[1] : null;

const scratchDesktopMatches = window.location.href.match( /[?&]isScratchDesktop=([^&]+)/ ); let simulateScratchDesktop; if (scratchDesktopMatches) { try { simulateScratchDesktop = JSON.parse(scratchDesktopMatches[1]); } catch { simulateScratchDesktop = scratchDesktopMatches[1]; } }

if (process.env.NODE_ENV === 'production' && typeof window === 'object') { window.onbeforeunload = () => true; }

ReactDOM.render( {simulateScratchDesktop ? ( ) : ( )} , appTarget ); };

我昨天做的。

Hi @Tom-cy thanks for your answer! I see you are importing the Router, but where are you using it? 🤔

@Tom-cy
Copy link

Tom-cy commented Oct 29, 2024

emmmmm, this ?

<Router basename="/scratch3">
    <Switch>
        {/* 默认路由 */}
        <Route exact path="/">
            {simulateScratchDesktop ? (
                <WrappedGui
                    canEditTitle
                    isScratchDesktop
                    showTelemetryModal
                    canSave={false}
                    onTelemetryModalCancel={handleTelemetryModalCancel}
                    onTelemetryModalOptIn={handleTelemetryModalOptIn}
                    onTelemetryModalOptOut={handleTelemetryModalOptOut}
                />
            ) : (
                <WrappedGui
                    canEditTitle
                    backpackVisible
                    showComingSoon
                    backpackHost={backpackHost}
                    canSave={false}
                    onClickLogo={onClickLogo}
                />
            )}
        </Route>

      
        <Route path="/editor">
            <EditorComponent />
        </Route>
        
        <Route path="/profile">
            <ProfileComponent />
        </Route>

   
        <Route path="/project/:projectId">
            <ProjectComponent />
        </Route>

  
        <Route path="*">
            <NotFoundComponent />
        </Route>
    </Switch>
</Router>

@aquino-luane
Copy link
Author

@Tom-cy thank you! it helped a lot, I was configuring the route in the wrong place instead of render-gui.jsx. I also need to show projectId in the address bar like you /project/:projectId. What is the ProjectComponent, what it shows? could you share what is in the ProjectComponent?

@aquino-luane
Copy link
Author

@Tom-cy sorry but I have one more question 🙇‍♀️
After you setup router dom, does the icons failed to load? if so, how you fixed it?
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants