Как исправить ошибку «отправка не является функцией» в собственном проекте - PullRequest
0 голосов
/ 24 апреля 2020

В реактивном, избыточном проекте Firebase у меня есть компонент-ящик, который подписывается на прослушиватель onSnapshot, когда компонент монтируется, и при отключении он вызывает ссылку на снимок. этот компонент выглядит следующим образом:

import { onAccountChange } from '../actions/Agenda';    
import {dispatch} from 'redux';

class DrawerContentComponent extends React.Component {
    constructor (props) {
        super(props);
    }
    componentDidMount(){
        this.unsubscribeAccount = firebase.firestore().collection('users').doc(this.props.authUser.uid).onSnapshot((doc) => {
        dispatch({type: types.LOAD_ACCOUNT, payload: doc.data()})

    });
    }
    componentWillUnmount() {
        this.unsubscribeAccount();
    }

    < ...rest of component... >

EDIT:
    const mapStateToProps = ({ account, auth, inbox, agenda }) => {
    const { role, profileImg, legalName, username, rating, phoneNumber } = account;
    const { conversations } = inbox;
    const { authUser } = auth;
    const { events } = agenda;
    return {
        role,
        profileImg,
        legalName,
        username,
        rating,
        phoneNumber,
        authUser,
        conversations,
        events
    };
};

    const mapDispatchToProps = { logoutUser, onProfileChange, onAccountChange, getConversations, getAgenda };

    export default connect(mapStateToProps, mapDispatchToProps)(DrawerContentComponent);
} 

Редактировать: onAccountChange():

export const onAccountChange = (uid) => {
    return (dispatch) => {
      firebase.firestore().collection('users').doc(uid).onSnapshot((doc) => {
        dispatch({ type: types.LOAD_ACCOUNT, payload: doc.data() });
      });
    };
};

Приведенные выше функции работают по мере необходимости, поскольку мне не удалось отписаться от действия, которое ранее был помещен во внешний каталог для действий.

Проблема: я хочу иметь возможность реализовать это, каким-то образом используя функцию, которая уже создана в файле действий (getAgenda()), без необходимости переписывать код в компоненте, потому что в настоящее время я делаю это просто иметь возможность отписаться от слушателя на unmount, только так, как я думал, чтобы это работало.

в идеале, id хотел бы сделать что-то вроде этого:

componentDidMount() {
  this.unsubscribeAgenda = this.props.getAgenda();
}
componentWillUnmount() {
  this.unsubscribeAgenda();
}

Но вышеприведенное приводит к: TypeError: 'dispatch is not a function', если я удалю dispatch импорт, ошибка будет ReferenceError: Cant find variable: dispatch Мне, очевидно, нужно отправить изменения для onSnapshot слушателя

Какие существуют стратегии для этого?

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Вы не можете импортировать диспетчеризацию напрямую из redux.

Вам нужно либо использовать функциюact-redux connect (), чтобы обернуть создателей действий диспетчеризацией, либо получить диспетчеризацию непосредственно из нее. * Если вы используете функциональный компонент, вы можете использовать useDispatch, чтобы получить к нему доступ.

Если вы не хотите использовать один из обычных вариантов реагирования с избыточностью, вы можете экспортировать диспетчеризацию из вашего сохранить, а затем импортировать его из того места, где вы создали свое хранилище.

export const dispatch = store.dispatch

Если большая часть вашей логики c для пожарного хранилища находится в режиме избыточного потока (или аналогична асинхронным возможностям), используйте команду connect to оберните действие в диспетчерское управление и запустите его, как в идеале в конце. Все, что вы возвращаете из действия thunk, также возвращается из вызова, поэтому вы должны иметь возможность настроить его так, чтобы оно возвращало функцию отмены подписки.

 connect({},{onAccountChange})(DrawerContentComponent)

Затем вы можете отправить на создателя действия onAccountChange, используя:

this.props.onAccountChange()

Редактировать:

Измените свою функцию onAccountChange на такую, чтобы ваш thunk возвращал вашу функцию unsubscibe.

export const onAccountChange = (uid) => {
  return (dispatch) => {
    return firebase
      .firestore()
      .collection('users')
      .doc(uid)
      .onSnapshot((doc) => {
        dispatch({ type: types.LOAD_ACCOUNT, payload: doc.data() });
      });
  };
};

Затем вам просто нужно добавить onAccountChange к mapDispatch, чтобы реквизиты и используйте это в вашем componentDidMount методе:

this.unsubscribeAccount = this.props.onAccountChange();
0 голосов
/ 24 апреля 2020

Для создания компонентов, которые будут прикреплены к хранилищу как для действий отправки, так и для сопоставления реквизитов, он используется с connect(mapStateToProps, mapDispatchToProps)(Component). в вашем случае пропускается компонент, поэтому я просто отправлю null для mapStateToProps

(при условии, что вы использовали Provider в каком-либо родительском компоненте REDUX. Я не могу понять, как подключить компонент, определенный как класс, расширяющий React.Component для чтения хранилища )


 import { connect } from 'react-redux';

 class DrawerContentComponent extends React.Component {
    ...rest code...
   componentDidMount() {
     this.unsubscribeAgenda = this.props.getAgenda();
    }
   componentWillUnmount() {
    this.unsubscribeAgenda();
    }
   }
  export default connect(null, { getAgenda })(DrawerContentComponent)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...