winjs / react-winjs

React wrapper around WinJS's controls
MIT License
206 stars 47 forks source link

SplitView Problem with React Router #44

Open mush42 opened 7 years ago

mush42 commented 7 years ago

Hi,

I am facing a problem with Winjs and React Router when using the SplitView component.

Those are my components:


<Router>
  <App />
<Router>

``` app.js
<MySplitView>
  <Route exact path="/" component={Home}/>
</MySplitView>

```mySplitView.js
<Winjs.SplitView
  style={{height: "calc(100% - 48px)"}}
  paneComponent={<div>Navigation</div>}
  contentComponent={<div>{this.props.children}</div>}
  onAfterClose={this.handleAfterClose}
  closedDisplayMode="inline"
  openedDisplayMode="inline"
  paneOpened={this.state.paneOpened}/>

The error message is:
"TypeError: _ref2 is undefined
computeMatch"

And when using the `Switch` component from `react-router' I get a diffrent error regarding the context:
"TypeError: this.context.router is undefined"

So, I suggest that the SplitView component does not initialize the context correctly. 
calliostro commented 7 years ago

Good luck to get help or a fix. WinJS is dead - dead like Windows Mobile. I would not start a new app based on WinJS.

mush42 commented 7 years ago

I am experimenting with it because it has an out-of-the-box accessibility support (for those who use screen readers and other assistive technologies)

hbj commented 6 years ago

This is probably a bit late but in case it helps someone, below is how I'm using SplitView with react router. The impotant bit here is to add the router to the content component and not use it as root element as usual, get a ref to it and use it for navigation in the handlers of the commands in the pane component.

app.js

import React from 'react';
import ReactWinJS from 'react-winjs';

import {
    BrowserRouter as Router,
    Route
} from 'react-router-dom';

const splitViewId = "mainSplitView";

const P1 = () => <div>P1</div>;
const P2 = () => <div>P2</div>;
const P3 = () => <div>P3</div>;

class App extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            date: new Date().toString(),
            paneOpened: false
        };

        this.handleTogglePane = this.handleTogglePane.bind(this);
        this.handleAfterClose = this.handleAfterClose.bind(this);
    }

    navigateTo(path) {
        this.router.history.push(path);
    }

    handleTogglePane() {
        this.setState({ paneOpened: !this.state.paneOpened });
    }

    handleAfterClose() {
        this.setState({ paneOpened: false });
    }

    handleNaviagate(path) {
        this.navigateTo(path);

        this.setState({
            paneOpened: false
        });
    }

    componentDidMount() {
        this.navigateTo('/');
    }

    render() {
        var paneComponent = (
            <div>
                <div>
                    <ReactWinJS.SplitViewPaneToggle
                        aria-controls={splitViewId}
                        paneOpened={this.state.paneOpened}
                        onInvoked={this.handleTogglePane} />
                </div>

                <ReactWinJS.SplitView.Command
                    label="Home"
                    icon="home"
                    onInvoked={this.handleNaviagate.bind(this, '/')} />
                <ReactWinJS.SplitView.Command
                    label="Favorite"
                    icon="favorite"
                    onInvoked={this.handleNaviagate.bind(this, '/p2')} />
                <ReactWinJS.SplitView.Command
                    label="Settings"
                    icon="settings"
                    onInvoked={this.handleNaviagate.bind(this, '/p3')} />
            </div>
        );

        var contentComponent = (
            <Router ref={(router) => { this.router = router; }}>
                <div>
                    <header id="mainHeader">
                        <ReactWinJS.SplitViewPaneToggle
                            aria-controls={splitViewId}
                            paneOpened={this.state.paneOpened}
                            onInvoked={this.handleTogglePane} />
                        <h1 className="win-type-header">Title</h1>
                        <div className="date">{this.state.date}</div>
                    </header>

                    <div>
                        <Route exact path="/" component={P1} />
                        <Route path="/p2" component={P2} />
                        <Route path="/p3" component={P3} />
                    </div>
                </div>
            </Router>
        );

        return (
            <ReactWinJS.SplitView
                id={splitViewId}
                closedDisplayMode="none"
                paneComponent={paneComponent}
                contentComponent={contentComponent}
                paneOpened={this.state.paneOpened}
                onAfterClose={this.handleAfterClose} />
        );
    }
}

export default App;