imperium2335
imperium2335

Reputation: 24132

ReactJS show/hide div with buttons

I have:

MainScreen:

import React from 'react';
import LeftNavigation from './LeftNavigation';
import DocumentTitle from 'react-document-title';

export default class MainScreen extends React.Component {

    render() {
        return (
            <div className="MainScreen">
                <DocumentTitle title='Main Screen'>
                    <LeftNavigation />
                    <RightPanel />
                </DocumentTitle>
            </div>
        )
    }
}

LeftNavigation:

import React from 'react';
import Tab from './Tab';

export default class LeftNavigation extends React.Component {

    static contextTypes = {
        getStore: React.PropTypes.func.isRequired
    };

    componentWillMount() {
        this.setState({
            active_tab: 'basics'
        })
    }

    onClick(e) {
        this.setState({
            active_tab: e
        })
    }

    render() {
        return (
            <div>
                <div className="tab-container">
                    <Tab onClick={this.onClick.bind(this, 'basics')} name="Basics" icon="basics.png" active={this.state.active_tab == 'basics'}/>
                    <Tab onClick={this.onClick.bind(this, 'rooms')} name="Rooms" icon="room.png" active={this.state.active_tab == 'rooms'}/>
                    <Tab onClick={this.onClick.bind(this, 'documents')} name="Documents" icon="documents.png" active={this.state.active_tab == 'documents'}/>
                    <Tab onClick={this.onClick.bind(this, 'images')} name="Images" icon="images.png" active={this.state.active_tab == 'images'}/>
                    <Tab onClick={this.onClick.bind(this, 'restrictions')} name="Restrictions" icon="restrictions.png" active={this.state.active_tab == 'restrictions'}/>
                    <Tab onClick={this.onClick.bind(this, '3d')} name="3D" icon="house.png" active={this.state.active_tab == '3d'}/>
                    <Tab onClick={this.onClick.bind(this, 'video')} name="Video" icon="video.png" active={this.state.active_tab == 'video'}/>
                </div>
            </div>
        )
    }
}

I want those buttons to control the visibility of divs container within RightPanel. How can I pass the active_tab state back up to LeftNavigation and then into RightPanel?


Some tweaks to the answer got it working:

import React from 'react';
import Tab from './Tab';

export default class LeftNavigation extends React.Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <div className="tab-container">
                    <Tab onClick={this.props.onTabSelected.bind(null, 'basics')} name="Basics" icon="basics.png" active={this.props.activeTab == 'basics'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, 'rooms')} name="Rooms" icon="room.png" active={this.props.activeTab == 'rooms'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, 'documents')} name="Documents" icon="documents.png" active={this.props.activeTab == 'documents'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, 'images')} name="Images" icon="images.png" active={this.props.activeTab == 'images'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, 'restrictions')} name="Restrictions" icon="restrictions.png" active={this.props.activeTab == 'restrictions'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, '3d')} name="3D" icon="house.png" active={this.props.activeTab == '3d'}/>
                    <Tab onClick={this.props.onTabSelected.bind(null, 'video')} name="Video" icon="video.png" active={this.props.activeTab == 'video'}/>
                </div>
            </div>
        )
    }
}

import React from 'react';
import LeftNavigation from './LeftNavigation';
import DocumentTitle from 'react-document-title';

export default class MainScreen extends React.Component {

    componentWillMount() {
        this.setState({
            activeTab: 'basics'
        })
    }

    handleTab(tab) {
        this.setState({
            activeTab: tab
        })
    }

    render() {
        return (
            <div className="MainScreen">
                <DocumentTitle title='Main Screen'>
                    <LeftNavigation onTabSelected={this.handleTab.bind(this)} activeTab={this.state.activeTab}/>
                </DocumentTitle>
            </div>
        )
    }
}

Upvotes: 0

Views: 688

Answers (1)

djskinner
djskinner

Reputation: 8125

Generally when you come across this situation you need to hoist your state up a level or two. Keeping your state as high in the component tree as possible is good practice.

In this case MainScreen becomes responsible for managing the active tab state and passing it down to its child components.

LeftNavigation can influence the active tab state by calling a prop that is passed down to it from MainScreen

export default class MainScreen extends React.Component {

    componentWillMount() {
        this.setState({
            active_tab: 'basics'
        })
    }

    handleTab(tab) {
        this.setState({
            active_tab: tab
        })
    } 

    render() {
        return (
            <div className="MainScreen">
                <DocumentTitle title='Main Screen'>
                    <LeftNavigation onTabSelected={this.handleTab.bind(this)} activeTab={this.state.activeTab} />
                    <RightPanel activeTab={this.state.activeTab} />
                </DocumentTitle>
            </div>
        )
    }
}

export default class LeftNavigation extends React.Component {

    static propTypes = {
        activeTab: PropTypes.string.isRequired,
        handleTab: PropTypes.func.isRequired
    } 

    render() {
        return (
            <div>
                <div className="tab-container">
                    <Tab onClick={this.handleTab.bind(null, 'basics')} name="Basics" icon="basics.png" active={this.props.active_tab == 'basics'}/>
                    <Tab onClick={this.handleTab.bind(null, 'rooms')} name="Rooms" icon="room.png" active={this.props.active_tab == 'rooms'}/>
                    <Tab onClick={this.handleTab.bind(null, 'documents')} name="Documents" icon="documents.png" active={this.props.active_tab == 'documents'}/>
                    <Tab onClick={this.handleTab.bind(null, 'images')} name="Images" icon="images.png" active={this.props.active_tab == 'images'}/>
                    <Tab onClick={this.handleTab.bind(null, 'restrictions')} name="Restrictions" icon="restrictions.png" active={this.props.active_tab == 'restrictions'}/>
                    <Tab onClick={this.handleTab.bind(null, '3d')} name="3D" icon="house.png" active={this.props.active_tab == '3d'}/>
                    <Tab onClick={this.handleTab.bind(null, 'video')} name="Video" icon="video.png" active={this.props.active_tab == 'video'}/>
                </div>
            </div>
        )
    }
}

Upvotes: 3

Related Questions