#javascript #reactjs #firebase #redux #react-redux
#javascript #reactjs #firebase #переопределение #реагировать-redux
Вопрос:
Я пытаюсь настроить аутентификацию с помощью Firebase и Redux. Когда я пытаюсь войти в систему, я получаю сообщение об ошибке: «Неперехваченный ошибка типа: объект (…) не является функцией»
Вот мой компонент «Login»:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { signIn } from '../store/actions/authActions'
class Login extends Component {
constructor(props){
super(props);
this.state={
email:'',
password:''
};
this.onChangeEmail=this.onChangeEmail.bind(this);
this.onChangePassword =this.onChangePassword.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChangeEmail(e) {
this.setState({
email:e.target.value
});
}
onChangePassword(e){
this.setState({
password:e.target.value
});
}
onSubmit(e){
e.preventDefault();
this.props.signIn(this.state);
}
render() {
return(
<div className="container">
<div className="row">
<div className="col-sm-9 col-md-7 col-lg-5 mx-auto">
<div className="card card-signin my-5">
<div className="card-body">
<h5 className="card-title text-center">Sign In</h5>
<form className="form-signin" onSubmit={this.onSubmit}>
<div className="form-label-group">
<label>Email address
<input type="email" id="inputEmail" className="form-control" placeholder="Email address" value={this.state.email} onChange={this.onChangeEmail} required autoFocus />
</label>
</div>
<div className="form-label-group">
<label>Password
<input type="password" id="inputPassword" className="form-control" placeholder="Password"
value={this.state.password}
onChange={this.onChangePassword}
required />
</label>
</div>
<div className="custom-control custom-checkbox mb-3">
<input type="checkbox" className="custom-control-input" id="customCheck1" />
<label className="custom-control-label" >Remember password
</label>
</div>
<button className="btn btn-lg btn-primary btn-block text-uppercase" type="submit">Sign in</button>
<hr className="my-4" />
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
const mapDispatchToProps = (dispatch) => {
return {
signIn: (creds) => dispatch(signIn(creds))
}
}
export default connect(null, mapDispatchToProps) (Login);
Вот мой создатель действия —> authAction.js
export const signIn = (credentials) => {
return (dispatch, getState, {getFirebase}) => {
const firebase = getFirebase();
firebase.auth().signInWIthEmailandPassword(
credentials.email,
credentials.password
).then(()=> {
dispatch ({ type: 'LOGIN_SUCCESS'})
}).catch((err) => {
dispatch('LOGIN_ERROR', err)
})
}
}
Вот мой редуктор —> authReducer.js
const initialState = {
authError: null
}
const authReducer = (state = initialState, action) => {
switch (action.type){
case 'LOGIN_ERROR':
console.log('Login Success')
return {
...state,
authError: 'Login Failed'
}
case 'LOGIN_SUCCESS':
console.log('Login Success');
return {
...state,
authError: null
}
default:
return state;
}
}
export default authReducer;
Отправка сопоставляется компоненту, потому что я могу видеть это, когда я console.log(this.props) в компоненте Login. Но я не понимаю, чего мне не хватает. Я использую ‘redux-thunk’ в качестве промежуточного программного обеспечения. Может быть, это проблема?
Вот мой ‘index.js ‘ файл, в котором я настраиваю свое промежуточное программное обеспечение:
import React from 'react';
import ReactDOM from 'react-dom';
import Root from './components/Root'
import './style.css';
import 'bootstrap/dist/css/bootstrap.css';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase';
import rootReducer from './store/reducers/rootReducer';
import configFB from './config/configFB'
import * as serviceWorker from './serviceWorker';
const store = createStore(rootReducer,
compose(
applyMiddleware(thunk.withExtraArgument(getFirebase)),
reactReduxFirebase(configFB), // redux binding for firebase
)
);
ReactDOM.render(<Root store={store} />, document.getElementById('root'));
У меня есть песочница с кодом, расположенным здесь!
Комментарии:
1. « return (dispatch, getState, getFirebase) => { const firebase = getFirebase(); … } « вам не нужны скобки в getFirebase
2. Когда я убираю скобки, ошибка возвращается как «getFirebase не является функцией».
3. Возможно, совместно используйте codesandbox.
4. В песочнице нет вашего кода?
5. Извините, исправлено —> codesandbox.io/s/p9v25xm3l7?fontsize=14
Ответ №1:
Теперь есть способ импортировать ` { withFirebase } из ‘react-redux-firebase’, что затем позволяет превратить компонент в компонент более высокого порядка.
import React, { Component } from 'react';
import { withFirebase } from 'react-redux-firebase'
class Login extends Component {
state={
email:‘’,
password:‘’
};
onChangeEmail = (e) => {
this.setState({
email:e.target.value
});
}
onChangePassword = (e) => {
this.setState({
password:e.target.value
});
}
onSubmit = (e) => {
e.preventDefault();
this.props.firebase.login(this.state).catch(err =>
console.log(err.message))
}
return(
Component Markup
)
export default withFirebase(Login);
Когда вы оборачиваете компонент в функцию withFirebase(), это превращает компонент в компонент более высокого порядка и делает определенные функции firebase доступными для компонента в качестве реквизитов. отсюда this.props.firebase.login()
в функции onSubmit(). Мне не нужно было действие для входа в систему.
Ответ №2:
Я столкнулся с этой ошибкой при попытке использовать перехватчики в более старой версии react. Решением было обновить версию react. Это, вероятно, относится и к попыткам импортировать другие несуществующие свойства пакета.