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

Posted

技术标签:

【中文标题】React Redux - 使用导航菜单设置存储和更新 UI【英文标题】:React Redux - Setting Store and Updating UI using Navigation Menu 【发布时间】: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” 请看我更新的答案 【参考方案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 只能是展示组件

以上是关于React Redux - 使用导航菜单设置存储和更新 UI的主要内容,如果未能解决你的问题,请参考以下文章

当使用 react-redux v5 设置 React v15.5 时,路由不导航

react-router-redux 5:维护导航中的商店状态历史记录

在 react redux 应用程序中手动导航时状态丢失

Redux 使用 react-router-redux 连接“块”导航

在 Redux 中没有 React Navigation 状态的 React Native 中的 Redux

刷新后 React-Redux 状态丢失