Могу ли я использовать более одного действия в компоненте в Redux - PullRequest
0 голосов
/ 25 января 2020

У меня есть два действия: userIdContainer и projectContainer.

В componentDidmount я использую эти действия для получения данных своих проектов и идентификатора пользователя

В проекте. js:

import React , {Component} from "react";
import ProjectCard from "../Partials/Project/ProjectCard";
import AddNewProject from "../Partials/Project/AddNewProject";
import { connect } from "react-redux";
import { userIdContainer } from "../../actions";
import { projectContainer } from "../../actions";
import $ from "jquery";
import { project } from "../../reducers/project";

class Projects extends Component{
  state = {
    projects : [],
  }

  componentDidMount = () =>{
    let token = localStorage.getItem('access_token');
    let config = {
      headers: {'Authorization': "bearer " + token}
    };
    axios.get( 
      '/api/projects',
      config
    ).then(response =>{
      let {projects , userId } = response.data;
      this.props.dispatch(userIdContainer(userId));
      this.props.dispatch(projectContainer(projects));
      this.setState({
        projects : projects
      })
    }).catch(error =>{

    });
  }

  render(){
    console.log(this.props);
    let projects = this.props.projects;
    let aProjects = [];
    if (projects) {
      aProjects = $.map(projects , function(value , index){
        return [<ProjectCard key={index} project={value} />];
      });
    }
    return(
      <div className="card-container">
        {aProjects}
        <AddNewProject />
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return{
    projects : state.project.projects,
    userId : state.auth.userId
  }
}

export default connect(mapStateToProps)(Projects);

в индексе. js (мои действия)

export const userIdContainer = (userId) => {
  return{
    type : 'USER_ID_CONTAINER',
    userId
  }
};
export const projectContainer = (project) => {
  // console.log(project);
  return {
    type : 'PROJECT_CONTAINER',
    project
  }
}

после визуализации этого компонента, userId возвращает неопределенное значение,

Если я удалить projectContainer действие, userIdContainer работает правильно.

Каков наилучший способ использовать более одного действия в этом компоненте?

я использовал комбинированный редуктор

import { combineReducers } from "redux";
import { auth } from "./auth";
import { project } from "./project";

export default combineReducers({
    auth,
    project
})

это мой авторский редуктор

export const auth = (state =[] , action ) => {
    // console.log(action.type);
    switch (action.type) {
        case 'IS_TOKEN_VALID' :
            // console.log(action);
            return {
                    token : action.token,
                    isUserLoggedIn : true
                }
            case 'USER_ID_CONTAINER' :
                return {
                        userId : action.userId
                    }
        default :
            return 'default';
    }
}

и проектный редуктор ...

export const project = (state =[] , action ) => {
    switch (action.type) {
        case 'PROJECT_CONTAINER' :
            return {
                    ...state , 
                    projects : action.project
                }
        default :
            return 'default';
    }
}

1 Ответ

1 голос
/ 25 января 2020

Как говорит https://redux.js.org/basics/reducers,

Мы возвращаем предыдущее состояние в случае по умолчанию. Важно вернуть предыдущее состояние для любого неизвестного действия.

Причина этого - Redux передает действие всем редукторам. То есть, когда вы делаете this.props.dispatch(projectContainer(projects));, оба редуктора называются.

Вам нужно заменить

default :
  return 'default';

на

default :
  return state;

в обоих редукторах.

Кроме того, когда вам это нравится, вы полностью перезаписываете состояние:

return {
  token : action.token,
  isUserLoggedIn : true
}

return {
  userId : action.userId
}

Возможно, вам придется изменить его на

return {
  ...state,
  token : action.token,
  isUserLoggedIn : true
}

return {
  ...state,
  userId : action.userId
}
...