React + Redux。在减速器中调度事件时。两个减速器获得相同的数据

时间:2019-01-17 19:43:09

标签: reactjs redux

我最近开始将redux用于新的个人项目。在我开始使用“ combineReducers”之前,它一直运行良好。每当我单击“提取待办事项”时,我的用户和待办事项还原器都会得到更新,即使它们具有不同的数据字段名称,它们都将获得相同的数据。现在我可能在这里做了一些错误的封装。但是,无论我浏览文档的频率如何,我都看不到自己在做错什么。

我的商店初始化脚本:

import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';

import toDoReducer from './todos/reducer';
import userReducer from './users/reducer';

const rootReducer = combineReducers({
    todosSlice: toDoReducer,
    usersSlice: userReducer
});

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));

export default store;

被注入索引:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/app/App';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';

import configureStore  from './store/configureStore';

ReactDOM.render(<Provider store={ configureStore }><App /></Provider>, document.getElementById('root'));

serviceWorker.unregister();

我的应用保留了todo容器的逻辑

import React, { Component } from 'react';
import { connect } from 'react-redux';

import * as todoActions from '../../store/todos/actions';
import UserContainer from '../usersContainer/UserContainer';

class App extends Component {

  componentDidMount() {
    console.log(this.props);
  }

  render() {
    let loading = '';
    let error = '';
    let todos = [];

    // check whether the component is fetching data
    this.props.loading === true ? loading = <p>Loading...</p> : loading = '';

    // check if there was an error
    this.props.error  && this.props.loading === false ? error = <p>There was an error</p> : error = '';

    // map the todos in the desired html markup.
    todos = this.props.todos.map( todo => {
      return <div key={todo.id}>  name: {todo.title} </div>
    });

    return (
      <div className="App">

        {/* <UserContainer /> */}

        {loading}
        {error}

        <p onClick={() => this.props.onFetchTodos()}>Fetch Todos</p>

        {todos}
      </div>
    );
  }
}


const mapStateToProps = state => {
  return {
    error: state.todosSlice.error,
    loading: state.todosSlice.loading,
    todos: state.todosSlice.todos
  }
}

const mapDispatchToProps = dispatch => {
  return {
    onFetchTodos: () => dispatch(todoActions.fetchTodos())
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

具有以下操作:

import axios from 'axios';
export const FETCH_TODOS = 'FETCH_TODOS';
export const GET_TODOS_STARTED = 'GET_TODOS_STARTED';
export const FETCH_TODOS_SUCCESS = 'FETCH_TODOS_SUCCESS';
export const FETCH_TODOS_FAILURE = 'FETCH_TODOS_FAILURE';

export const fetchRequest = () => {
    return dispatch => {

        dispatch(getTodoStarted());

        axios.get('https://one365-api-dev.azurewebsites.net/api/teams/')
            .then(result => {
                dispatch(fetchTodosSucces(result));
            }).catch(error => {
                dispatch(fetchTodoFailure(error));
            });
    }

}

const getTodoStarted = () => ({
    type: GET_TODOS_STARTED
});

const fetchTodosSucces = todos => ({
    type: FETCH_TODOS_SUCCESS,
    payload: {
      ...todos
    }
});

const fetchTodoFailure = error => ({
    type: FETCH_TODOS_FAILURE,
    payload: {
      error
    }
});

export const fetchTodos = () => {
    return (dispatch => {
        dispatch(fetchRequest());
    });
}

它是减速器

import * as actions from './actions';

const initialState = {
    error: null,
    loading: false,
    todos: []
}

const todosReducer = (state = initialState, action) => {

    switch(action.type) {

        case actions.GET_TODOS_STARTED: {
            console.log('fetch todo state', state)

            return {
                ...state,
                loading: state.loading = true
            };
        }

        case actions.FETCH_TODOS_SUCCESS: {
            const todos = action.payload.data;
            return {
                ...state,
                loading: false,
                todos: state.todos = todos
            };
        }

        case actions.FETCH_TODOS_FAILURE: {
            const error = action.payload.error;

            return {
                ...state,
                loading: false,
                error: state.error = error
            };
        }

        default: {
            return state;
        }
    }
}

export default todosReducer;

用户组件

    import React from 'react';
    import { connect } from 'react-redux';

    import * as userActions from '../../store/users/actions';

    class UserContainer extends React.Component {

        render () {
            let loading = '';
            let error = '';
            let users = [];

            // check whether the component is fetching data
            this.props.usersLoading === true ? loading = <p>Loading...</p> : loading = '';

            // check if there was an error
            this.props.usersError  && this.props.loading === false ? error = <p>There was an error</p> : error = '';

            // map the users in the desired html markup.
            users = this.props.users.map( user => {
              return <div key={user.id}>  name: {user.title} </div>
            });

            return (
              <div className="Users">

                {loading}
                {error}

                <p onClick={() => this.props.onFetchUsers()}>Fetch Users</p>

                {users}
              </div>
            );
        }
    }

    const mapStateToProps = state => {
        return {
            usersError: state.usersSlice.error,
            usersLoading: state.usersSlice.loading,
            users: state.usersSlice.users
        }
    }

    const mapDispatchToProps= (dispatch) => {
        return {
            onFetchUsers: () => dispatch(userActions.fetchUsers())
        }    
    }

    export default connect(mapStateToProps, mapDispatchToProps)(UserContainer);

the user actions:
import axios from 'axios';
export const FETCH_USERS = 'FETCH_TODOS';
export const FETCH_USERS_STARTED = 'GET_TODOS_STARTED';
export const FETCH_USERS_SUCCESS = 'FETCH_TODOS_SUCCESS';
export const FETCH_USERS_FAILURE = 'FETCH_TODOS_FAILURE';


export const fetchRequest = () => {
    return dispatch => {
        dispatch(fetchUsersStarted());

        axios.get('https://one365-api-dev.azurewebsites.net/api/me')
            .then(result => {
                dispatch(fetchUsersSuccess(result));
            }).catch(error => {
                dispatch(fetchUsersFailure(error));
            });
    }
}


export const fetchUsersSuccess = (users) => {
    return {
        type: FETCH_USERS_SUCCESS,
        payload: {
            ...users
        }
    }
}

export const fetchUsersStarted = () => ({
    type: FETCH_USERS_STARTED
});

export const fetchUsersFailure = (error) => {
    return {
        type: FETCH_USERS_FAILURE,
        payload: {
            error
        }
    }
}



export const fetchUsers = () => {
    return dispatch =>  {
        dispatch(fetchRequest()) 
    }
};

它是减速器:

import * as actions from './actions';

const initialState = {
    error: '',
    loading: false,
    users: []
}

const userReducer = (state = initialState, action) => {

    switch(action.type) {

        case actions.FETCH_USERS_STARTED:  {
            console.log('fetch users state', state)
            return {
                ...state,
                loading: state.loading = true
            }
        } 

        case actions.FETCH_USERS_SUCCESS: {
            const users = action.payload.data;
            return {
                ...state,
                loading: false,
                users: state.users = users
            }
        }

        case actions.FETCH_USERS_FAILURE: {
            const error = state.payload.error;
            return {
                ...state,
                loading: false,
                error: state.error = error    
            }
        }

        default: {
            return state;
        }
    }

}


export default userReducer;

现在,当我运行DEV服务器时,我只会看到“提取待办事项”按钮。我对点击处理程序的用户进行了注释,以查看是否是事件气泡上升。但事实并非如此。

应用加载后,redux开发工具将显示以下状态: enter image description here

但是一旦我单击提取待办事项的处理程序。待办事项和用户都感到满足。 enter image description here

我非常感谢阅读了很多(样板)代码的人。我可能在封装状态时遇到了问题。但是再次阅读许多教程后,我仍然找不到我的问题。

1 个答案:

答案 0 :(得分:2)

您有复制/粘贴问题。您更改了“ USERS”操作的常量名称,但保留了与“ TODOS”操作相同的值。

export const FETCH_USERS = 'FETCH_TODOS';
export const FETCH_USERS_STARTED = 'GET_TODOS_STARTED';
export const FETCH_USERS_SUCCESS = 'FETCH_TODOS_SUCCESS';
export const FETCH_USERS_FAILURE = 'FETCH_TODOS_FAILURE';

我认为您打算拥有:

export const FETCH_USERS = 'FETCH_USERS';
export const FETCH_USERS_STARTED = 'FETCH_USERS_STARTED';
export const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS';
export const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE';