Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 当我分派一个操作时,没有调用Redux-Reducer_Reactjs_Redux_Redux Thunk - Fatal编程技术网

Reactjs 当我分派一个操作时,没有调用Redux-Reducer

Reactjs 当我分派一个操作时,没有调用Redux-Reducer,reactjs,redux,redux-thunk,Reactjs,Redux,Redux Thunk,我有一个简单的react应用程序,它从本地的JSON中获取数据并更新状态。我面临的问题是,当我发送操作时,没有调用我的减速机。我可以看到dispatch从JSON获得响应,但状态没有更新 我在reducer上做了一个console.log,但运气不好。我检查了Redux开发工具,但没有看到状态更新。这是我的密码 store.js import {createStore, compose, applyMiddleware} from 'redux' import thunk from 'redux

我有一个简单的react应用程序,它从本地的JSON中获取数据并更新状态。我面临的问题是,当我发送操作时,没有调用我的减速机。我可以看到dispatch从JSON获得响应,但状态没有更新

我在reducer上做了一个console.log,但运气不好。我检查了Redux开发工具,但没有看到状态更新。这是我的密码

store.js

import {createStore, compose, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {routerMiddleware} from 'react-router-redux'
import rootReducer from './combined.reducer'
import {createLogger} from 'redux-logger'

let middlewares = [
    thunk
]

const logger = createLogger();

if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test") {
    middlewares = [
        ...middlewares,
        logger,
        require("redux-immutable-state-invariant").default()
    ]
}

export default function configureStore(history) {
    const composeEnhancers =
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const enhancer = composeEnhancers(
        applyMiddleware(...middlewares, routerMiddleware(history))
    );
    const store = createStore(
        rootReducer(history),
        enhancer
    )

    if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test" && module.hot) {
        module.hot.accept("./combined.reducer", () => {
            const nextReducer = require("./combined.reducer").default
            store.replaceReducer(nextReducer)
        })
    }

    return store
import { connectRouter } from 'connected-react-router';
import { combineReducers } from 'redux';
import * as workoutReducer from './features/WorkoutList/Containers/Workout.Reducer'

const createAppReducer = (history) => combineReducers({
  router: connectRouter(history),
  workoutReducer: workoutReducer
})

const rootReducer = (history) => (state, action) => {
  return createAppReducer(history)(state,action)
};

export default rootReducer;
import constants from "./Workout.Constants"


const initialState = {
    workoutListData :{}
}

 function reducer(state = initialState, action) {
  console.log(".................I'm here................")
     switch(action.type) {
         case constants.GET_WORKOUT_LIST_SUCCESS: {
         return Object.assign({}, state, {
             workoutListData: action.response.GET_LIST_DATA
         })
        }
          case constants.GET_WORKOUT_LIST_FAILURE: {
          return Object.assign({}, state, initialState)    
        } 
     default:
     return state
    }
 }

 export {initialState}
 export default reducer
组合的.reducer.js

import {createStore, compose, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {routerMiddleware} from 'react-router-redux'
import rootReducer from './combined.reducer'
import {createLogger} from 'redux-logger'

let middlewares = [
    thunk
]

const logger = createLogger();

if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test") {
    middlewares = [
        ...middlewares,
        logger,
        require("redux-immutable-state-invariant").default()
    ]
}

export default function configureStore(history) {
    const composeEnhancers =
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const enhancer = composeEnhancers(
        applyMiddleware(...middlewares, routerMiddleware(history))
    );
    const store = createStore(
        rootReducer(history),
        enhancer
    )

    if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test" && module.hot) {
        module.hot.accept("./combined.reducer", () => {
            const nextReducer = require("./combined.reducer").default
            store.replaceReducer(nextReducer)
        })
    }

    return store
import { connectRouter } from 'connected-react-router';
import { combineReducers } from 'redux';
import * as workoutReducer from './features/WorkoutList/Containers/Workout.Reducer'

const createAppReducer = (history) => combineReducers({
  router: connectRouter(history),
  workoutReducer: workoutReducer
})

const rootReducer = (history) => (state, action) => {
  return createAppReducer(history)(state,action)
};

export default rootReducer;
import constants from "./Workout.Constants"


const initialState = {
    workoutListData :{}
}

 function reducer(state = initialState, action) {
  console.log(".................I'm here................")
     switch(action.type) {
         case constants.GET_WORKOUT_LIST_SUCCESS: {
         return Object.assign({}, state, {
             workoutListData: action.response.GET_LIST_DATA
         })
        }
          case constants.GET_WORKOUT_LIST_FAILURE: {
          return Object.assign({}, state, initialState)    
        } 
     default:
     return state
    }
 }

 export {initialState}
 export default reducer
文件夹结构:

src
 features
   Workout
     Components
     Containers
       Workout.Actions.js
       Workout.Constants.js
       Workout.Container.js
       Workout.Reducer.js
       Workout.js
const constants = {
    GET_WORKOUT_LIST_REQUEST: "GET_WORKOUT_LIST_REQUEST",
    GET_WORKOUT_LIST_SUCCESS: "GET_WORKOUT_LIST_SUCCESS",
    GET_WORKOUT_LIST_FAILURE: "GET_WORKOUT_LIST_FAILURE"
    }

export default constants
import { connect } from 'react-redux'
import {withRouter} from 'react-router'
import {bindActionCreators} from 'redux'
import Workout from './Workout'
import * as workoutAction from './Workout.Actions'

export default withRouter(connect(
    (state) => ({
        workoutListData: state.workoutListData
    }), 
    (dispatch) => ({
        workoutActions:bindActionCreators(workoutAction, dispatch)
    })
)(Workout))
import constants from "./Workout.Constants"
import {getConfigProperty} from "../../../settings"
import {makeGetCall} from "../../../utils/Api"
const WORKOUT_LIST = getConfigProperty("workoutList")

export function getWorkoutList(url = WORKOUT_LIST) {
    return (dispatch, getState) => {
        dispatch(getWorkoutListRequest(true))
        return makeGetCall(url, getState)
            .then(res => res.json())
            .then(json => {
                dispatch(getWorkoutListSuccess(json))
                dispatch(getWorkoutListRequest(false))
            })
            .catch(ex => {
                dispatch(getWorkoutListFailure(ex))
                dispatch(getWorkoutListRequest(false))
            })
    }
}

export function getWorkoutListRequest(req) {
    return {
        type: constants.GET_WORKOUT_LIST_REQUEST,
        req
    }
}

export function getWorkoutListSuccess(response) {
    return {
        type: constants.GET_WORKOUT_LIST_SUCCESS, 
        response
    }
}

export function getWorkoutListFailure(exception) {
    return {
        type: constants.GET_WORKOUT_LIST_FAILURE,
        exception
    }
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {WorkoutListItem} from './../StyledComponents/WorkoutListItem'
import {isEmpty, isEqual} from 'lodash'
import {getConfigProperty} from "../../../settings"
const ROWS_PER_PAGE = getConfigProperty("rowsPerPage")



export default class Workout extends Component {


    static get PropTypes() {
        return {
            workoutListData: PropTypes.array.isRequired
        }
    }


    constructor(props){
        super(props)


     this.state = {
        workoutListData: []
     }
    }

    componentWillMount(){
        if(isEmpty(this.props.workoutListData)){
            this.props.workoutActions.getWorkoutList()
        }     
    } 


    loadWorkoutListItem = () => {
        return <WorkoutListItem / >
    }

    render() {
        return (
            <div>
                {this.loadWorkoutListItem()}
            </div>)
    }
}
Workout.Constants.js:

src
 features
   Workout
     Components
     Containers
       Workout.Actions.js
       Workout.Constants.js
       Workout.Container.js
       Workout.Reducer.js
       Workout.js
const constants = {
    GET_WORKOUT_LIST_REQUEST: "GET_WORKOUT_LIST_REQUEST",
    GET_WORKOUT_LIST_SUCCESS: "GET_WORKOUT_LIST_SUCCESS",
    GET_WORKOUT_LIST_FAILURE: "GET_WORKOUT_LIST_FAILURE"
    }

export default constants
import { connect } from 'react-redux'
import {withRouter} from 'react-router'
import {bindActionCreators} from 'redux'
import Workout from './Workout'
import * as workoutAction from './Workout.Actions'

export default withRouter(connect(
    (state) => ({
        workoutListData: state.workoutListData
    }), 
    (dispatch) => ({
        workoutActions:bindActionCreators(workoutAction, dispatch)
    })
)(Workout))
import constants from "./Workout.Constants"
import {getConfigProperty} from "../../../settings"
import {makeGetCall} from "../../../utils/Api"
const WORKOUT_LIST = getConfigProperty("workoutList")

export function getWorkoutList(url = WORKOUT_LIST) {
    return (dispatch, getState) => {
        dispatch(getWorkoutListRequest(true))
        return makeGetCall(url, getState)
            .then(res => res.json())
            .then(json => {
                dispatch(getWorkoutListSuccess(json))
                dispatch(getWorkoutListRequest(false))
            })
            .catch(ex => {
                dispatch(getWorkoutListFailure(ex))
                dispatch(getWorkoutListRequest(false))
            })
    }
}

export function getWorkoutListRequest(req) {
    return {
        type: constants.GET_WORKOUT_LIST_REQUEST,
        req
    }
}

export function getWorkoutListSuccess(response) {
    return {
        type: constants.GET_WORKOUT_LIST_SUCCESS, 
        response
    }
}

export function getWorkoutListFailure(exception) {
    return {
        type: constants.GET_WORKOUT_LIST_FAILURE,
        exception
    }
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {WorkoutListItem} from './../StyledComponents/WorkoutListItem'
import {isEmpty, isEqual} from 'lodash'
import {getConfigProperty} from "../../../settings"
const ROWS_PER_PAGE = getConfigProperty("rowsPerPage")



export default class Workout extends Component {


    static get PropTypes() {
        return {
            workoutListData: PropTypes.array.isRequired
        }
    }


    constructor(props){
        super(props)


     this.state = {
        workoutListData: []
     }
    }

    componentWillMount(){
        if(isEmpty(this.props.workoutListData)){
            this.props.workoutActions.getWorkoutList()
        }     
    } 


    loadWorkoutListItem = () => {
        return <WorkoutListItem / >
    }

    render() {
        return (
            <div>
                {this.loadWorkoutListItem()}
            </div>)
    }
}
Workout.Container.js:

src
 features
   Workout
     Components
     Containers
       Workout.Actions.js
       Workout.Constants.js
       Workout.Container.js
       Workout.Reducer.js
       Workout.js
const constants = {
    GET_WORKOUT_LIST_REQUEST: "GET_WORKOUT_LIST_REQUEST",
    GET_WORKOUT_LIST_SUCCESS: "GET_WORKOUT_LIST_SUCCESS",
    GET_WORKOUT_LIST_FAILURE: "GET_WORKOUT_LIST_FAILURE"
    }

export default constants
import { connect } from 'react-redux'
import {withRouter} from 'react-router'
import {bindActionCreators} from 'redux'
import Workout from './Workout'
import * as workoutAction from './Workout.Actions'

export default withRouter(connect(
    (state) => ({
        workoutListData: state.workoutListData
    }), 
    (dispatch) => ({
        workoutActions:bindActionCreators(workoutAction, dispatch)
    })
)(Workout))
import constants from "./Workout.Constants"
import {getConfigProperty} from "../../../settings"
import {makeGetCall} from "../../../utils/Api"
const WORKOUT_LIST = getConfigProperty("workoutList")

export function getWorkoutList(url = WORKOUT_LIST) {
    return (dispatch, getState) => {
        dispatch(getWorkoutListRequest(true))
        return makeGetCall(url, getState)
            .then(res => res.json())
            .then(json => {
                dispatch(getWorkoutListSuccess(json))
                dispatch(getWorkoutListRequest(false))
            })
            .catch(ex => {
                dispatch(getWorkoutListFailure(ex))
                dispatch(getWorkoutListRequest(false))
            })
    }
}

export function getWorkoutListRequest(req) {
    return {
        type: constants.GET_WORKOUT_LIST_REQUEST,
        req
    }
}

export function getWorkoutListSuccess(response) {
    return {
        type: constants.GET_WORKOUT_LIST_SUCCESS, 
        response
    }
}

export function getWorkoutListFailure(exception) {
    return {
        type: constants.GET_WORKOUT_LIST_FAILURE,
        exception
    }
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {WorkoutListItem} from './../StyledComponents/WorkoutListItem'
import {isEmpty, isEqual} from 'lodash'
import {getConfigProperty} from "../../../settings"
const ROWS_PER_PAGE = getConfigProperty("rowsPerPage")



export default class Workout extends Component {


    static get PropTypes() {
        return {
            workoutListData: PropTypes.array.isRequired
        }
    }


    constructor(props){
        super(props)


     this.state = {
        workoutListData: []
     }
    }

    componentWillMount(){
        if(isEmpty(this.props.workoutListData)){
            this.props.workoutActions.getWorkoutList()
        }     
    } 


    loadWorkoutListItem = () => {
        return <WorkoutListItem / >
    }

    render() {
        return (
            <div>
                {this.loadWorkoutListItem()}
            </div>)
    }
}
Workout.Actions.js:

src
 features
   Workout
     Components
     Containers
       Workout.Actions.js
       Workout.Constants.js
       Workout.Container.js
       Workout.Reducer.js
       Workout.js
const constants = {
    GET_WORKOUT_LIST_REQUEST: "GET_WORKOUT_LIST_REQUEST",
    GET_WORKOUT_LIST_SUCCESS: "GET_WORKOUT_LIST_SUCCESS",
    GET_WORKOUT_LIST_FAILURE: "GET_WORKOUT_LIST_FAILURE"
    }

export default constants
import { connect } from 'react-redux'
import {withRouter} from 'react-router'
import {bindActionCreators} from 'redux'
import Workout from './Workout'
import * as workoutAction from './Workout.Actions'

export default withRouter(connect(
    (state) => ({
        workoutListData: state.workoutListData
    }), 
    (dispatch) => ({
        workoutActions:bindActionCreators(workoutAction, dispatch)
    })
)(Workout))
import constants from "./Workout.Constants"
import {getConfigProperty} from "../../../settings"
import {makeGetCall} from "../../../utils/Api"
const WORKOUT_LIST = getConfigProperty("workoutList")

export function getWorkoutList(url = WORKOUT_LIST) {
    return (dispatch, getState) => {
        dispatch(getWorkoutListRequest(true))
        return makeGetCall(url, getState)
            .then(res => res.json())
            .then(json => {
                dispatch(getWorkoutListSuccess(json))
                dispatch(getWorkoutListRequest(false))
            })
            .catch(ex => {
                dispatch(getWorkoutListFailure(ex))
                dispatch(getWorkoutListRequest(false))
            })
    }
}

export function getWorkoutListRequest(req) {
    return {
        type: constants.GET_WORKOUT_LIST_REQUEST,
        req
    }
}

export function getWorkoutListSuccess(response) {
    return {
        type: constants.GET_WORKOUT_LIST_SUCCESS, 
        response
    }
}

export function getWorkoutListFailure(exception) {
    return {
        type: constants.GET_WORKOUT_LIST_FAILURE,
        exception
    }
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {WorkoutListItem} from './../StyledComponents/WorkoutListItem'
import {isEmpty, isEqual} from 'lodash'
import {getConfigProperty} from "../../../settings"
const ROWS_PER_PAGE = getConfigProperty("rowsPerPage")



export default class Workout extends Component {


    static get PropTypes() {
        return {
            workoutListData: PropTypes.array.isRequired
        }
    }


    constructor(props){
        super(props)


     this.state = {
        workoutListData: []
     }
    }

    componentWillMount(){
        if(isEmpty(this.props.workoutListData)){
            this.props.workoutActions.getWorkoutList()
        }     
    } 


    loadWorkoutListItem = () => {
        return <WorkoutListItem / >
    }

    render() {
        return (
            <div>
                {this.loadWorkoutListItem()}
            </div>)
    }
}
锻炼.Reducer.js

import {createStore, compose, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {routerMiddleware} from 'react-router-redux'
import rootReducer from './combined.reducer'
import {createLogger} from 'redux-logger'

let middlewares = [
    thunk
]

const logger = createLogger();

if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test") {
    middlewares = [
        ...middlewares,
        logger,
        require("redux-immutable-state-invariant").default()
    ]
}

export default function configureStore(history) {
    const composeEnhancers =
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
    const enhancer = composeEnhancers(
        applyMiddleware(...middlewares, routerMiddleware(history))
    );
    const store = createStore(
        rootReducer(history),
        enhancer
    )

    if (process.env.Node_ENV !== "production" && process.env.Node_ENV !== "test" && module.hot) {
        module.hot.accept("./combined.reducer", () => {
            const nextReducer = require("./combined.reducer").default
            store.replaceReducer(nextReducer)
        })
    }

    return store
import { connectRouter } from 'connected-react-router';
import { combineReducers } from 'redux';
import * as workoutReducer from './features/WorkoutList/Containers/Workout.Reducer'

const createAppReducer = (history) => combineReducers({
  router: connectRouter(history),
  workoutReducer: workoutReducer
})

const rootReducer = (history) => (state, action) => {
  return createAppReducer(history)(state,action)
};

export default rootReducer;
import constants from "./Workout.Constants"


const initialState = {
    workoutListData :{}
}

 function reducer(state = initialState, action) {
  console.log(".................I'm here................")
     switch(action.type) {
         case constants.GET_WORKOUT_LIST_SUCCESS: {
         return Object.assign({}, state, {
             workoutListData: action.response.GET_LIST_DATA
         })
        }
          case constants.GET_WORKOUT_LIST_FAILURE: {
          return Object.assign({}, state, initialState)    
        } 
     default:
     return state
    }
 }

 export {initialState}
 export default reducer
workout.js:

src
 features
   Workout
     Components
     Containers
       Workout.Actions.js
       Workout.Constants.js
       Workout.Container.js
       Workout.Reducer.js
       Workout.js
const constants = {
    GET_WORKOUT_LIST_REQUEST: "GET_WORKOUT_LIST_REQUEST",
    GET_WORKOUT_LIST_SUCCESS: "GET_WORKOUT_LIST_SUCCESS",
    GET_WORKOUT_LIST_FAILURE: "GET_WORKOUT_LIST_FAILURE"
    }

export default constants
import { connect } from 'react-redux'
import {withRouter} from 'react-router'
import {bindActionCreators} from 'redux'
import Workout from './Workout'
import * as workoutAction from './Workout.Actions'

export default withRouter(connect(
    (state) => ({
        workoutListData: state.workoutListData
    }), 
    (dispatch) => ({
        workoutActions:bindActionCreators(workoutAction, dispatch)
    })
)(Workout))
import constants from "./Workout.Constants"
import {getConfigProperty} from "../../../settings"
import {makeGetCall} from "../../../utils/Api"
const WORKOUT_LIST = getConfigProperty("workoutList")

export function getWorkoutList(url = WORKOUT_LIST) {
    return (dispatch, getState) => {
        dispatch(getWorkoutListRequest(true))
        return makeGetCall(url, getState)
            .then(res => res.json())
            .then(json => {
                dispatch(getWorkoutListSuccess(json))
                dispatch(getWorkoutListRequest(false))
            })
            .catch(ex => {
                dispatch(getWorkoutListFailure(ex))
                dispatch(getWorkoutListRequest(false))
            })
    }
}

export function getWorkoutListRequest(req) {
    return {
        type: constants.GET_WORKOUT_LIST_REQUEST,
        req
    }
}

export function getWorkoutListSuccess(response) {
    return {
        type: constants.GET_WORKOUT_LIST_SUCCESS, 
        response
    }
}

export function getWorkoutListFailure(exception) {
    return {
        type: constants.GET_WORKOUT_LIST_FAILURE,
        exception
    }
}
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {WorkoutListItem} from './../StyledComponents/WorkoutListItem'
import {isEmpty, isEqual} from 'lodash'
import {getConfigProperty} from "../../../settings"
const ROWS_PER_PAGE = getConfigProperty("rowsPerPage")



export default class Workout extends Component {


    static get PropTypes() {
        return {
            workoutListData: PropTypes.array.isRequired
        }
    }


    constructor(props){
        super(props)


     this.state = {
        workoutListData: []
     }
    }

    componentWillMount(){
        if(isEmpty(this.props.workoutListData)){
            this.props.workoutActions.getWorkoutList()
        }     
    } 


    loadWorkoutListItem = () => {
        return <WorkoutListItem / >
    }

    render() {
        return (
            <div>
                {this.loadWorkoutListItem()}
            </div>)
    }
}
import React,{Component}来自“React”
从“道具类型”导入道具类型
从“/../StyledComponents/WorkoutListItem”导入{WorkoutListItem}
从“lodash”导入{isEmpty,isEqual}
从“../../../settings”导入{getConfigProperty}
const ROWS\u PER\u PAGE=getConfigProperty(“rowsPerPage”)
导出默认类组件{
静态get PropTypes(){
返回{
workoutListData:PropTypes.array.isRequired
}
}
建造师(道具){
超级(道具)
此.state={
workoutListData:[]
}
}
组件willmount(){
如果(isEmpty(this.props.workoutListData)){
this.props.workoutActions.getWorkoutList()文件
}     
} 
loadWorkoutListItem=()=>{
回来
}
render(){
返回(
{this.loadWorkoutListItem()}
)
}
}
应该调用reducer函数。我甚至没有看到控制台日志打印出来

我想你不需要

import * as workoutReducer from './features/WorkoutList/Containers/Workout.Reducer'
但只是

import workoutReducer from './features/WorkoutList/Containers/Workout.Reducer'
第一种方法是将initialState和reducer作为组合对象导入,而不仅仅是导入reducer


编辑:这是在
combined.reducer.js

中,就是这样。谢谢,泽克。它帮助解决了问题,很高兴能帮上忙!