0

I have to dynamically generate the navigation tab, navigation tab-list will be having many tabs (For Ex: home, about etc..). When I click any "tab" it should get active and its color should change. to achieve this I am using this object structure- [{id: 1,name:"home",selected: true}, ... ] The Idea is: when I click any tab "selected" should be "TRUE" for that particular tab, and rest tab's "selected" value should become "FALSE". Tab is getting printed perfectly, but I am little confused about how to achieve "active" of tab. How do I achieve this?

My Application Structure + CODE is Below:

  • actions
    • tabaction.js
  • components
    • app.js
  • container
    • list.js
  • reducers
    • index.js
    • reducer-tab.js

index.js


index.js (entry page)

import 'babel-polyfill';
import React from 'react';
import ReactDOM from "react-dom";
import { Router, Route, IndexRoute, Link, IndexLink, browserHistory } from 'react-router';
import {Provider} from "react-redux";
import {createStore} from 'redux';
import allReducers from './reducers'
import App from './components/app'

const store = createStore(allReducers);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>
    , document.getElementById('root')
);

app.js (components)

import React from 'react';
import PlanList from '../container/list';

require('../../scss/style.scss');

const App = () => (
    <div>
        <PlanList />
    </div>
);

export default App;

list.js (container)

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {selectTab} from '../actions/tabaction';

class PlanList extends Component{

    createListItems(){

        return this.props.planlist.map((plan)=>{
            return (
                    <div className="planlist-card" key={plan.id}>{plan.first}</div>
                )
        });
    }

    render(){
        return(
            <div className="planlist-card-wrapper">
                <ul className="tabs">

                    {
                        this.props.tabs.map((tab, i) => {
                            return (
                                <li onClick={() => this.props.selectTab(tab)} key={i} className={tab.selected?'active':''}>
                                    <a href="#">{tab.name}</a>
                                </li>
                            )
                        })
                    }
                </ul>

                <h2>Dental Plan List: One way</h2>
                {this.createListItems()}
                <hr />
                <h2>Dental Plan List:: Another way</h2>
                {
                    this.props.planlist.map((plan, i) => {
                        return <div className="planlist-card" key={plan.id}>{plan.first}</div>
                    })
                }


            </div>  
        )
    }
}

function mapStateToProps(state){
    return {
        planlist: state.planlist,
        tabs: state.tabs
    }
}

function matchDispatchToProps(dispatch){
    return bindActionCreators({selectTab: selectTab}, dispatch)
}

export default connect(mapStateToProps, matchDispatchToProps)(PlanList);

tabaction.js (actions)

export const SELECT_PLAN_TAB = 'SELECT_PLAN_TAB';
export const selectTab = (tab) => {

    console.log('you clicked me', tab);
    tab.selected = true;
    return {
        type: SELECT_PLAN_TAB,
        payload: tab
    }
}

index.js (reducers)

import {combineReducers} from 'redux';
import UserReducer from './reducer-users';
import Tabs from './reducer-tab';

const allReducers = combineReducers({
    tabs: Tabs
});

export default allReducers;

reducer-tab.js (reducers)

export default function(){
    return [
        {
            id: 1,
            name:"home",
            selected: true
        },
        {
            id: 2,
            name:"about",
            selected: false
        },
        {
            id: 3,
            name:"contact",
            selected: false
        }
    ]
}
Raj Rj
  • 2,944
  • 4
  • 18
  • 31

1 Answers1

0

Since there is only one tab being active at a time, you might wanna create state.selectedTabId vs. making the selected state part of the tab object.

Also, move your state mutation where you update which tab is selected to a reducer. I would have a reducer take care of an action.type like "SELECT_TAB", where the action.payload has the ID of the tab being selected and you just return the ID. Make sure your reducer is for state.selectedTabId. (e.g. const store = createStore(combineReducers({ selectedTabId: selectedTabIdReducer }));)

In your component, you just read props.selectedTabId to see if you need to apply certain classNames/style etc...

Finally, you don't need to use redux for storing the state of the selected tab unless you need other connected components or their child components to have access to it easily while you scale the app. Only state that would be too complex to manage by using state and props by React should go to Redux.

goldbullet
  • 602
  • 4
  • 10