Как отправить действие и изменить объект в React-Redux? Мне нужно создать вкладку навигации

Мне нужно динамически создать вкладку навигации, в списке вкладок навигации будет много вкладок (например, главная, о и т. Д.). Когда я нажимаю на любую «вкладку», она должна стать активной, а ее цвет должен измениться. для этого я использую эту структуру объекта - [{id: 1, name: "home", selected: true}, ...] Идея такова: когда я нажимаю на любую вкладку, "selected" должно быть "TRUE" для этого определенная вкладка, а значение «selected» остальной вкладки должно стать «FALSE». Вкладка печатается отлично, но я немного не понимаю, как добиться «активности» вкладки. Как мне этого добиться?

Моя структура приложения + КОД:

  • actions
    • tabaction.js
  • components
    • app.js
  • container
    • list.js
  • reducers
    • index.js
    • редуктор-tab.js

index.js


index.js (страница входа)

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 (компоненты)

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

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

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

export default App;

list.js (контейнер)

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 (действия)

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 (редукторы)

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 (редукторы)

export default function(){
    return [
        {
            id: 1,
            name:"home",
            selected: true
        },
        {
            id: 2,
            name:"about",
            selected: false
        },
        {
            id: 3,
            name:"contact",
            selected: false
        }
    ]
}

person Raj Rj    schedule 25.08.2016    source источник


Ответы (1)


Поскольку одновременно активна только одна вкладка, вы можете создать state.selectedTabId вместо того, чтобы сделать выбранное состояние частью объекта вкладки.

Кроме того, переместите мутацию состояния туда, где вы обновляете, какая вкладка выбрана, в редуктор. Я хотел бы, чтобы редуктор позаботился о типе action.type, таком как «SELECT_TAB», где action.payload имеет идентификатор выбранной вкладки, а вы просто возвращаете идентификатор. Убедитесь, что ваш редуктор предназначен для state.selectedTabId. (например, const store = createStore(combineReducers({ selectedTabId: selectedTabIdReducer }));)

В своем компоненте вы просто читаете props.selectedTabId, чтобы узнать, нужно ли вам применить определенные имена классов / стиль и т. Д.

Наконец, вам не нужно использовать redux для хранения состояния выбранной вкладки, если вам не нужны другие подключенные компоненты или их дочерние компоненты, чтобы иметь легкий доступ к ней во время масштабирования приложения. Только состояние, которое было бы слишком сложным для управления с помощью состояния и свойств React, должно переходить в Redux.

person goldbullet    schedule 25.08.2016