【问题标题】:React Redux - Setting Store and Updating UI using Navigation MenuReact Redux - 使用导航菜单设置存储和更新 UI
【发布时间】:2017-06-25 02:41:31
【问题描述】:

我对 react/redux 非常陌生,在 Javascript 方面非常平庸,但我已经为此苦苦挣扎了一个多星期。这是我正在尝试做的事情: 单击左侧的导航菜单项应发送一个操作以在商店中设置选定的索引(此时整个商店只是一个数字)。当索引更新时,它应该自动反映在 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: 从“redux”导入 { createStore } 从'./Reducers'导入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 上没有任何反映。现在单击侧边栏项目时出现此错误:“无法读取未定义的属性'handleClick'”

提前感谢您的帮助。

【问题讨论】:

  • 我现在收到此错误:“app.bundle.js:22790 Uncaught ReferenceError: selectedSidebarItem is not defined”
  • 请看我更新的答案

标签: javascript reactjs redux react-redux


【解决方案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)

【讨论】:

  • 谢谢,这有帮助,我已经更新了我的帖子以反映变化
  • 更新“未捕获的 ReferenceError:未定义 selectedSidebarItem”后仍然出现相同的错误。我尝试在侧边栏的构造函数中设置此值,但似乎没有帮助。
  • 您必须根据我在 sidebar.js 中的回答更新 handleClick 方法主体。在你的例子中它仍然是错误的
  • 我这样做了,现在得到“无法读取未定义的属性 'selectedSidebarItem'”
  • 因为这个变量没有定义,你尝试将它传递给 SidebarItem 组件。一般来说,我认为您应该在 Sidebar 组件中调度操作,而 SidebarItem 只能是展示组件
猜你喜欢
  • 2020-04-17
  • 2020-10-15
  • 2017-07-10
  • 1970-01-01
  • 2021-10-10
  • 2016-06-17
  • 2020-08-16
  • 1970-01-01
  • 2019-07-22
相关资源
最近更新 更多