Как вызвать действие сразу после и только в том случае, если в React Redux с Thunk и Firebase существует реквизит - PullRequest
0 голосов
/ 29 октября 2019

У меня есть настроенное приложение с Firebase и Redux. На странице входа я проверяю вошедшего в систему пользователя, затем извлекаю userprofile с идентификатором, затем вытягиваю проект с пользователем projectid. Теперь вы можете нажать на кнопку, связанную с приборной панелью. В компоненте приборной панели я вытаскиваю карточки с уже полученным проектом. Но есть моя проблема. Когда я перезагружаю страницу, в проекте нет состояния. Поэтому я хочу проверить, есть ли проект, если нет, он должен вызвать предыдущие действия (поиск пользователя, профиль извлечения, проект проекта) и сразу после получения проекта он должен попытаться снова извлечь карты.

Я заканчиваю тем, что объединяю в цепочку все действия, но я не хочу вызывать все снова и снова только для того, чтобы получить одну опору.

Вот мой код:

App.js

imports...

class App extends Component {
  constructor(props){
    super(props)

    this.authListener()

  }

  authListener=()=>{
    firebase.auth().onAuthStateChanged((user)=>{
        if(user){
           this.props.setFirebaseUser(user)
           this.props.getUser(user.uid)    
        }   
    })
}

  componentDidUpdate(prevProps){
    if(prevProps.cUser !== this.props.cUser){
      // this.props.getProject(this.props.cUser.project)
    }
  }


  setInitialState=()=>{
    this.setState( {
      fUser:{},
      pUser:{},
      cUser:{},
      cProject:{},
      cCard:{},
      uCard:{}
    })
  }



  render(){
    return (
      <Router>
        ...
      </Router>
    );
  }

}
const mapStateToProps = state => ({
  cUser: state.auth.cUser,
  fireUser: state.auth.fireUser,
  cProject: state.auth.cProject
})
export default connect(mapStateToProps, {setFirebaseUser,getUser})(App)

В моем компоненте приложения все работает нормально.

Admin.js

import ...

class Admin extends Component {


    componentWillMount(){
        if(this.props.cProject.pid){
            this.props.getCards(this.props.cProject.pid)
        }else{
            //HOW TO DO THIS RIGHT?
            this.props.getUser(user)
            //then
            this.props.getCards(this.props.cProject.pid)
    }

    render() {
        return (  
            <div >
              ...
            </div> 
        )
    }
}


const mapStateToProps = state => ({
    cUser: state.auth.cUser,
    fireUser: state.auth.fireUser,
    cProject: state.auth.cProject,
    cards: state.card.cards
})

export default connect(mapStateToProps,{getCards, setFirebaseUser, getUser, getProject})(Admin)

Это мои действия. Мне уже приходилось связывать некоторые действия, но я не хочу вызывать действия, которые мне не нужны, например "getCards" в компонентах, у которых нет карт для отображения

authActions.js

imports...

export const setFirebaseUser = (user) =>dispatch=>{
    console.log('fired')
    dispatch({
        type: SET_FIREBASE_USER,
        payload: user
    })
}

export const getUser = (userid) => dispatch => {
    firebase.firestore().collection('Users').doc(userid).get()
    .then(user =>{
        dispatch({
            type: GET_USER,
            payload: user.data()
        })
        dispatch(
            getProject(user.data(), userid)
        )

    })
}
export const getProject = (user, userID) => dispatch=>{
    firebase.firestore().collection('Project').doc(user.project).get()
            .then(project =>{
                dispatch({
                    type: GET_PROJECT,
                    payload: project.data()
                })
                dispatch(
                    getProjectUser(user.project,userID)
                )
            })
}

export const getProjectUser = (projectID, userID) => dispatch=>{
    firebase.firestore().collection('Project').doc(projectID).collection('Users').doc(userID).get()
    .then((proUser)=>{
        dispatch({
            type: GET_PROJECT_USER,
            payload: proUser.data()
        })
    })
}

cardActions.js:

export const getCards = (projectID) => dispatch =>{
    firebase.firestore().collection('Project').doc(projectID).collection('Cards').get()
        .then(cards=>{
            cards.forEach(card => {
                console.log(card.data())
                dispatch({
                    type:GET_CARDS,
                    payload: card.data()
                })
            });
        })
}

Единственное, что сработало, - это цепочка всех действий, но если я это сделаю, я загрузил бы все данные в App.js, где мне это не нужно. Я хочу загрузить данные туда, где они мне нужны, и предварительно загрузить только необходимые данные.

...