首页 > 解决方案 > 将 Redux 映射状态反应到道具不起作用

问题描述

所以我正在尝试使用 Redux 学习 React,到目前为止,我认为我已经能够编写出使其工作所需的大部分代码,但是我在将状态传递给我的组件时遇到了问题。我正在使用具有 react 和 redux 样板代码的 Visual Studio 2017 的 ASP.NET Core 项目模板,他们使用了这个:

export default connect(
  state => state.weatherForecasts,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(FetchData);

我尝试用我自己的组件做同样的事情,如下所示:

export default connect(
  state => state.lecture,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(LectureTable);

但是当尝试访问我的道具的内容时,我想要获取的属性被标记为未定义。我通过 Redux devtools 检查了我的初始状态存在,但我的组件无法看到我试图传递给它的道具。奇怪的是我只是模仿了样板代码,但它没有工作,但样板代码工作得很好(即我可以转到组件并注销其初始状态)。

由于我遵循 Visual Studio 使用的格式,因此我的 actioncreators、reducers 和常量位于一个文件中,如下所示:

const GET_LECTURES = "GET_LECTURES";

const initialState = {
    lectures: [],
    selectedLecture: {},
    isLoading: false,
    test: 0
};

export const actionCreators = {
    requestLectures: isLoading => async (dispatch) => 
    {    
      if (!isLoading) {
        // Don't issue a duplicate request (we already have or are loading the requested data)
        return;
      }

      dispatch({ type: GET_LECTURES });

      const url = `api/lecture/`;
      const response = await fetch(url);
      const lectures = await response.json();

      dispatch({ type: RECEIVE_LECTURES, payload: lectures });
    } 
  };

export const reducer = (state = initialState, action) => {
    switch (action.type) {
    case GET_LECTURES:
        return { ...state, isLoading: true }; 
        default:
        return state;
    }
};

我很抱歉,如果一切都乱七八糟。我真的才刚刚开始了解redux ..

编辑 我的组件代码:

import React, { Component } from 'react';
import {Button, Table, Label, Menu, Icon} from 'semantic-ui-react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {actionCreators} from './../../store/Lecture';

export class LectureTable extends Component {

  componentWillMount(){
   // this.props.requestLectures(this.props.isLoading);
    console.log(this.props.test);
  }

  render() {
    return (
        <Table size='large'>
        {/*removed to make it cleaner..currently only has static data too lol*/}
      </Table>
    )
  }
}



export default connect(
  state => state.lecture,
  dispatch => bindActionCreators(actionCreators, dispatch)
)(LectureTable);

我的商店在哪里配置:

import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { routerReducer, routerMiddleware } from 'react-router-redux';
import * as Lecture from './Lecture';
import * as Counter from './Counter';
import * as WeatherForecasts from './WeatherForecasts';

export default function configureStore(history, initialState) {
  const reducers = {
    lecture: Lecture.reducer,
    counter: Counter.reducer,
    weatherForecasts: WeatherForecasts.reducer
  };

  const middleware = [
    thunk,
    routerMiddleware(history)
  ];

  // In development, use the browser's Redux dev tools extension if installed
  const enhancers = [];
  const isDevelopment = process.env.NODE_ENV === 'development';
  if (isDevelopment && typeof window !== 'undefined' && window.devToolsExtension) {
    enhancers.push(window.devToolsExtension());
  }

  const rootReducer = combineReducers({
    ...reducers,
    routing: routerReducer
  });

  return createStore(
    rootReducer,
    initialState,
    compose(applyMiddleware(...middleware), ...enhancers)
  );
}

我的 index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { createBrowserHistory } from 'history';
import configureStore from './store/configureStore';
import App from './pages/App';
import registerServiceWorker from './registerServiceWorker';

// Create browser history to use in the Redux store
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
const history = createBrowserHistory({ basename: baseUrl });

// Get the application-wide store instance, prepopulating with state from the server where available.
const initialState = window.initialReduxState;
const store = configureStore(history, initialState);

const rootElement = document.getElementById('root');

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  rootElement);

registerServiceWorker();

标签: javascriptreactjsredux

解决方案


connect()的第一个参数应该是一个返回对象的函数——你想要添加的道具作为键,它们的值是来自状态的值。例如

state => ({ lecture: state.lecture })

推荐阅读