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

React Redux - Setting Store and Updating UI using Navigation Menu

我是 react/redux 的新手,在 Javascript 上非常平庸,但我已经为此苦苦挣扎了一个多星期。这是我正在尝试做的事情: 单击左侧的导航菜单项之一应该会发送一个操作来设置商店中的选定索引(此时整个商店只是一个数字)。当索引更新时,它应该自动反映在 UI 中,至少通过更改所选项目的 css class,但最终它应该切换右侧内容组件的可见性.

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: 从 'redux' 导入 { createStore } 从 './Reducers'

导入减速器
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 上没有任何反映。现在单击侧边栏项目时出现此错误:"Cannot read property 'handleClick' of undefined"

提前感谢您的帮助。

在您的 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)