Redux状态显示为Map,无法访问combineReducers属性

问题描述 投票:0回答:1

在mapStateToProps中,它应该像访问你想要的状态部分的键一样简单,并获取状态参数,但我无法这样做。

主app.js文件

import React from 'react'
import ReactDom from 'react-dom'
import { Provider } from 'react-redux'
import { ConnectedRouter } from 'connected-react-router/immutable'
import { createBrowserHistory } from 'history'

import configureStore from './store/configureStore'

import App from './components/partials/App'

const history = createBrowserHistory()

const store = configureStore(history)

ReactDom.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <App/>
        </ConnectedRouter>
    </Provider>,
    document.getElementById('reactDiv')
)

configureStore.js

import { applyMiddleware, compose, createStore } from 'redux'
import { routerMiddleware } from 'connected-react-router/immutable'
import thunkMiddleware from 'redux-thunk'
import { combineReducers } from 'redux-immutable'
import { connectRouter } from 'connected-react-router'

import AppReducer from './reducers/app'

const createRootReducer = history => combineReducers({
        router: connectRouter(history),
        app: AppReducer
    })

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

export default function configureStore(history) {
    const middleware = [routerMiddleware(history), thunkMiddleware]

    const rootReducer = createRootReducer(history)

    return createStore(rootReducer, composeEnhancers(applyMiddleware(...middleware)))
}

appReducer

/**
 * App level reducer
 */
const initialState = {
    accounts: [],
    employees: []
}

const reducer = (state = initialState, action) => {
    switch(action.type) {
        case 'ACCOUNT_SELECTION_LIST_LOADED':
            return {...state, accounts: action.payload}
        case 'EMPLOYEE_SELECTION_LIST_LOADED':
            return {...state, employees: action.payload}
    }
    return state
}

export async function fetchAccountsSelectionList(dispatch, getState) {
    makeAjaxRequest('/getList/accounts', 'GET', null, response => {
        const accounts = JSON.parse(response)
        dispatch({type: 'ACCOUNT_SELECTION_LIST_LOADED', payload: accounts})
    })
}

export async function fetchEmployeesSelectionList(dispatch, getState) {
    makeAjaxRequest('/getList/employees', 'GET', null, response => {
        const employees = JSON.parse(response)
        dispatch({type: 'EMPLOYEE_SELECTION_LIST_LOADED', payload: employees})
    })
}

export default reducer

主要组件(缩小以节省空间)

import React, { Component } from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import { LinkContainer } from 'react-router-bootstrap'
import { FormControl, InputGroup, Navbar, Nav, NavDropdown, NavLink } from 'react-bootstrap'
import { connect } from 'react-redux'
import { fetchAccountsSelectionList, fetchEmployeesSelectionList } from '../../store/reducers/app'
import Select from 'react-select'
  
class App extends Component {
    constructor() {
        super()
        this.state =  {
            billId: '',
            invoiceId: '',
            manifestId: ''
        }
        this.handleChange = this.handleChange.bind(this)
    }

    componentDidMount() {
        this.props.fetchAccountsSelectionList()
        this.props.fetchEmployeesSelectionList()
    }

    handleChange(event) {
        const {name, checked, value, type} = event.target
        this.setState({[name]: type === 'checkbox' ? checked : value})
    }

    render() {
        return (
            <BrowserRouter>
                <Navbar variant='dark' bg='dark' className={'navbar-expand-lg', 'navbar'}>
                    <LinkContainer to='/'>
                        <Navbar.Brand>Fast Forward Express v2.0</Navbar.Brand>
                    </LinkContainer>
                    <Navbar.Toggle aria-controls='responsive-navbar-nav' />
                    <Navbar.Collapse id='responsive-navbar-nav'>
                        <Nav className='ml-auto'>
                            <NavDropdown title='Bills' id='navbar-bills'>
                            </NavDropdown>
                            <NavDropdown title='Invoices' id='navbar-invoices'>
                            </NavDropdown>
                            <NavDropdown title='Accounts' id='navbar-accounts' alignRight>
                            </NavDropdown>
                            <NavDropdown title='Employees' id='navbar-employees' alignRight>
                            </NavDropdown>
                            <LinkContainer to='/app/dispatch'><NavLink>Dispatch</NavLink></LinkContainer>
                            <NavDropdown title='Administration' id='navbar-admin' alignRight>
                            </NavDropdown>
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>
                <Switch>
                    <Route path='xxx' component={xxx}></Route>
                </Switch>
            </BrowserRouter>
        )
    }
}

const matchDispatchToProps = dispatch => {
    return {
        fetchAccountsSelectionList: () => dispatch(fetchAccountsSelectionList),
        fetchEmployeesSelectionList: () => dispatch(fetchEmployeesSelectionList)
    }
}

const mapStateToProps = state => {
    return {
         accounts: state.app.accounts,
         employees: state.app.employees
    }
}

export default connect(mapStateToProps, matchDispatchToProps)(App)

所以。当我注销 mapStateToProps 正在接收的“状态”时,它是一个 Map,而不是一个对象,如下所示:

state results

为什么我的状态看起来不像我看过的任何教程?我无法找到任何其他这样的示例,除了一个说只需手动迭代的示例 - 但由于这不是“正确”的方式,我必须错误地配置存储

我应该注意到,开发人员工具似乎能够完美地访问状态,并反映我期望看到的内容。为什么我无法访问 state.app.accounts

reactjs redux react-redux
1个回答
1
投票

问题是您使用的两个包依赖于 Immutable.js 数据结构,而不是普通的 JS 对象:

import { combineReducers } from 'redux-immutable'
和 import { routerMiddleware } from 'connected-react-router/immutable'。

特别是,来自

combineReducers
redux-immutable
将导致根状态对象成为 Immutable.js
Map
实例,而不是普通对象,并且
Map
实例具有
.get()
.set() 
方法而不是普通字段。

我们强烈建议反对此时在 Redux 应用程序中使用 Immutable.js

相反,您应该将状态编写为纯 JS 对象和数组,并且您应该使用 我们的官方 Redux Toolkit 包来设置您的存储并编写您的减速器。

请仔细阅读 Redux 核心文档中的官方 “Redux Essentials”“Redux Fundamentals” 教程,了解如何使用 Redux Toolkit 编写 Redux 逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.