React Redux - 使用导航菜单设置存储和更新UI

时间:2017-02-07 18:06:07

标签: javascript reactjs redux react-redux

我对Javascript的反应/减少非常新,而且非常平庸,但我现在已经在这方面苦苦挣扎了一个多星期。这就是我要做的事情: Rough mock-up 单击左侧的其中一个导航菜单项应调度操作以在商店中设置所选索引(此时整个商店只是一个数字)。当索引更新时,它应该自动反映在UI中,至少通过更改所选项的css类,但最终应切换右侧内容组件的可见性。

Sidebar.js:

import React, { Component } from 'react';
import SidebarItem from './SidebarItem'
import ActionCreators from '../actions'
import { connect } from 'react-redux'

export default class Sidebar extends Component
{   
    handleClick(index)
    {
        //Dispatch action here maybe?
        this.props.selectedSidebarItem(index);
        console.log(this);
    }
    render()
    {
        var sidebarItemNames = ["Verify Original Contract", "Evaluate Transfer Terms", "Create Future Customer", "Check Credit", "Generate Agreement", "Finalize Transfer"];
        return (            
                <div>
                    <div id="sidebar-title">
                        <div id="sc-logo">
                            LOGO
                        </div>
                        <div>Contract Transfer for:</div>
                        <div>XYZ</div>
                        <br />                  
                    </div>                                      
                    <ul className="list-group" id="sidebar-list">
                        {sidebarItemNames.map(function(n, index)
                        {
                            return <SidebarItem key={index} index={index} selectedIndex={this.selectedSidebarItem} name={n} handleClick={this.handleClick(index).bind(this)} />;
                        })}
                    </ul>
                </div>
            )
    }
}

function mapDispatchToProps(dispatch) {
  return {
    selectedSidebarItem: (index) => dispatch(ActionCreators.setSelectedSidebarItem(index))
  }
}
const conn = connect(
  null,
  mapDispatchToProps
)(Sidebar)

SidebarItem.js:

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

export class SidebarItem extends Component {

    constructor(props) {
        super(props);
    }
    setSelectedSidebarItem() {
        this.props.handleClick(this.props.index);
        this.props.selectedSidebarItem(this.props.index);    
        // const ul = document.getElementById('sidebar-list');
        // const items = ul.getElementsByTagName('li');
        // for (let i = 0; i < items.length; ++i) {
        //     items[i].classList.remove('sidebar-item-current');
        // }
    }

    render() {
        return (
            <li className={"list-group-item sidebar-list-item sidebar-item-todo" + (this.props.index==this.props.selectedIndex? ' sidebar-item-current':'') } onClick={this.setSelectedSidebarItem.bind(this)}><i className="fa fa-circle fa-lg"></i> <span>{this.props.name}</span></li>
        )
    }
}

Store.js:     从&#39; redux&#39;导入{createStore}     从&#39; ./ Reducers&#39;

导入Reducer
const store = createStore(reducers)

export default store

Reducers.js

const initialState = {
    selectedSidebarItem: window.initialPageState,
    otherStuff: 5
};
const reducers = (state = initialState, action) => {
    switch (action.type) {
        case "SET_SELECTED_SIDEBAR_ITEM":
        console.log("clicked sidebar index: " + action.index);
            var result = Object.assign({}, state, {
                selectedSidebarItem: action.index
            })
            console.log(result);
            return result;
        default:
            return state
    }
}

export default reducers

actions.js:

import constants from './constants'

let ActionCreators = {
    setSelectedSidebarItem(index) {
        var actionObject = {
            type: constants.UPDATE_SELECTED_SIDEBAR_ITEM,
            index
        }
        console.log("setting sidebar item", actionObject);

        return actionObject
    }
}
export default ActionCreators

Constants.js

const constants = { 
    UPDATE_SELECTED_SIDEBAR_ITEM: "UPDATE_SELECTED_SIDEBAR_ITEM",
    ADD_ERROR: "ADD_ERROR",
    CLEAR_ERROR: "CLEAR_ERROR"
};

export default constants;

我已经尝试了上述的一些变体,之前已经能够发送动作,但我不确定商店是否会更新,并且UI上没有任何反映。现在我点击侧边栏项时出现此错误:&#34;无法读取属性&#39; handleClick&#39;未定义&#34;

感谢您提前提供任何帮助。

1 个答案:

答案 0 :(得分:1)

你的sidebar.js中的

: 而不是

handleClick={() => this.handleClick(index).bind(this)}

试试这个:

handleClick={this.handleClick(index).bind(this)}

handleClick方法中,你必须发送行动:

this.props.selectedSidebarItem(index)

回答更新:

import React, { Component } from 'react';
import SidebarItem from './SidebarItem'
import ActionCreators from '../actions'
import { connect } from 'react-redux'

export default class Sidebar extends Component
{   
    handleClick(index)
    {
        //Dispatch action here maybe?
        this.props.selectedSidebarItem(index);
        this.selectedSidebarItem = index;
        console.log(this);
    }
    render()
    {
        var sidebarItemNames = ["Verify Original Contract", "Evaluate Transfer Terms", "Create Future Customer", "Check Credit", "Generate Agreement", "Finalize Transfer"];
        return (            
                <div>
                    <div id="sidebar-title">
                        <div id="sc-logo">
                            LOGO
                        </div>
                        <div>Contract Transfer for:</div>
                        <div>XYZ</div>
                        <br />                  
                    </div>                                      
                    <ul className="list-group" id="sidebar-list">
                        {sidebarItemNames.map(function(n, index)
                        {
                            return <SidebarItem key={index} index={index} selectedIndex={this.selectedSidebarItem} name={n} handleClick={this.handleClick(index).bind(this)} />;
                        })}
                    </ul>
                </div>
            )
    }
}

function mapDispatchToProps(dispatch) {
  return {
    selectedSidebarItem: (index) => dispatch(ActionCreators.setSelectedSidebarItem(index))
  }
}
const conn = connect(
  null,
  mapDispatchToProps
)(Sidebar)