Linked Questions

Popular Questions

layouts flow in react router v4

Asked by At

My app currently has three components, User to view a person's profile, Self for a user to view their dashboard, notifications, and settings and a login page.

Both User and Self share common components Nav and Side, where User would pass the self object and call the fetchUser action from redux to Nav and Side, while Self would pass the user and self object along with calling the fetchSelf action.

User.js

class User extends React.Component {
    componentDidMount() {
        this.props.fetchUser(this.props.username);
    }

    render() {

        const { page, self, user } = this.props

        return (
            <main>

                <Nav 
                    self={self} 
                />

                <Side  
                    page={page} user={user} 
                />

                <div>
                     .....
                </div>

            </main>
        )
    }
}

const mapStateToProps = state => ({
    page: state.store.page,
    self: state.store.self
});

export default connect(mapStateToProps, {fetchUser})(User);

Self.js

class Self extends React.Component {
    componentDidMount() {
        this.props.fetchSelf();
    }

    render() {

        const { page, self } = this.props

        return (
            <main>

                <Nav 
                    self={self} 
                />

                <Side  
                    page={page} self={self} 
                />

                {
                    tab === 'Dashboard'
                    ? <Dashboard />
                    : tab === 'Notifications'
                        ? <Notifications />
                        : tab === 'Settings'
                            ? <Settings />
                            : null
                }

            </main>
        )
    }
}

const mapStateToProps = state => ({
    page: state.store.page,
    self: state.store.self
});

export default connect(mapStateToProps, {fetchSelf})(Self);

Login.js

class Login extends React.Component {
    .....

    handleChange = event => {
        .....
    }


    render() {

        return (
            <div id="login">
                .....
            </div>
    )
}

Side.js

const Side = (props) => {

    const { page, self, user } = props;

    return (

        <aside>
        {
            page === 'user'

            ?   <div>
                    <img src={'img/' + user.profile.avatar} alt={`${user.username}'s avatar`} />
            </div>

            :   <div>
                    <img src={'img/' + self.profile.avatar} alt={`${self.username}'s avatar`} />
                <div>   
        }
        </aside>
    )
}

What I'd like to do here is instead of using react-router like this

<BrowserRouter>
    <Switch>
        <Route path="/login" exact={true} component={Login} />  
        <Route path="/self" exact={true} component={Self} />    
        <Route path="/:username" component={User} />  
    </Switch>
</BrowserRouter>

I'd want to be able to do something like this instead

const LayoutForLoginAndSignup = (props) => {
    return (
        <div class="loginOrSignUp">
            <ComponentToBePassedIn />
        </div>
    )
}

class LayoutWithNavAndSide extends React.Component  {
    componentDidMount() {
        this.props.fetchSelf();
        // this.props.fetchUser('someusername')
    }

    render() {
        return (
            <main>
                <Nav self={this.props.self} />
                <Side page={this.props.page} self={this.props.self} user={this.props.user} />
                {Content of component that was passed in}
            </main>
        )
    }
}

const mapStateToProps = state => ({
    page: state.store.page,
    self: state.store.self,
    user: state.store.user
});

export default connect(mapStateToProps, {fetchUser, fetchSelf})(LayoutWithNavAndSide);



<BrowserRouter>
    <Switch>
        <LayoutForLoginAndSignup path="/login" exact={true} component={Login} />  
        <LayoutWithNavAndSide path='/self' component={Self} />
        <LayoutWithNavAndSide path="/:username" component={User} />  
    </Switch>
</BrowserRouter>

Here's where I get confused as I'm still new to react/redux/react router, how do I get the component of User or Self to show up in the layout? how do I get it to call fetchUser (on componentDidMount) only if someone is accessing /someuser vice versa with fetchSelf only when they goto the /self route? is it possible to do the layout as a function rather than a class?

Related Questions