我在登录过程中第一次应用redux-thunk。我收到以下错误(红色屏幕):
这是我的代码回购: https://github.com/samrao2/manager-4
以下代码段:
LoginForm.js:
我的代码仓库在这里:https://github.com/samrao2/manager-4
代码片段:
Actions / index.js:
import firebase from 'firebase';
import { EMAIL_CHANGED,
PASSWORD_CHANGED,
LOGIN_USER_SUCCESS
} from './types';
//whenever the const variable below (action creator) is called
//it will be called with some amount of text and it returns an action, the text
//which is entered as an argument becomes the payload below
export const emailChanged = (text) => {
return {
type: EMAIL_CHANGED,
payload: text
};
};
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
};
export const loginUser = ({ email, password }) => {
//since we are using redux thunk/ async, the action creator now returns a function
//instead of an object. Redux Thunk will see that this is a function and run it
//the "then" will dispatch once the function is finisehd running
return (dispatch) => {
firebase.auth().signInWithEmailAndPassword(email, password)
.then(user => {
dispatch({ type: LOGIN_USER_SUCCESS, payload: user });
});
};
};
loginform.js:
//we need this component to use react components library
import React, { Component } from 'react';
//this connect helper that will connect the action to the login form
import { connect } from 'react-redux';
//this is an action creator that we need to import in to connect with the reducers
import { emailChanged, passwordChanged, loginUser } from '../actions';
//these are our pre-styled components
import { Card, CardSection, Input, Button } from './common';
//login form is declared as an instance of the class "component"
class Loginform extends Component {
// this is the event handler as a method whose argument is text
onEmailChange(text) {
//we have access to this prop from the action creator that is connected via the connect helper
this.props.emailChanged(text);
}
onPasswordChange(text) {
this.props.passwordChanged(text);
}
onButtonPress() {
const { email, password } = this.props;
this.props.loginUser({ email, password });
}
render() {
return (
<Card>
<CardSection>
<Input
label="Email"
placeholder="email@gmail.com"
onChangeText={this.onEmailChange.bind(this)}
//this comes from mapStateToProps and WE tell the component what its value is
//via the action creator and the reducer
value={this.props.email}
/>
</CardSection>
<CardSection>
<Input
secureTextEntry
label="Password"
placeholder="password"
onChangeText={this.onPasswordChange.bind(this)}
value={this.props.password}
/>
</CardSection>
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}>
Login
</Button>
</CardSection>
</Card>
);
}
}
//this function is from the react-redux library and helps to map some piece of state
//onto the component
const mapStateToProps = state => {
return {
//the global state object contains another object called auth, which containts the email
//property
email: state.auth.email,
password: state.auth.password
};
};
//we are connecting/binding our action creator via the connect helper
//mapStateToProps is the first argument in the connect function
export default connect(mapStateToProps, {
emailChanged, passwordChanged, loginUser
})(Loginform);
REDUCER:
//this is importing the email changed variable instead of the string in the action
import { EMAIL_CHANGED,
PASSWORD_CHANGED
} from '../actions/types';
//we need to do this otherwise the initial value will be undefined and the
//action will not work
const INITIAL_STATE = {
email: '',
password: ''
};
//this is the reducer below, its got 2 arguments, the state and action
export default (state = INITIAL_STATE, action) => {
console.log(action);
//this switch statement switches over the action type, and depending on type
//the action decides what to do with it
switch (action.type) {
case EMAIL_CHANGED:
console.log('action!');
//make a new object, take all the properties of my current object and include in
//that new object and take the email action.payload and include/overwrite that
//in the new object created
return { ...state, email: action.payload };
case PASSWORD_CHANGED:
return { ...state, password: action.payload };
//if none of the cases come out to be true above, it will default to the
//beginning state with no changes
default:
return state;
}
};
App.js:
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import firebase from 'firebase';
//reduxthnunk is helping us with aync operations, its a middlware
//to help with this middleware we need a ahelper from Redux library
//
import ReduxThunk from 'redux-thunk';
import reducers from './reducers';
import LoginForm from './components/LoginForm';
class App extends Component {
componentWillMount() {
const config = {
apiKey: 'AIzaSyCCEY-CD1iSpSowupPZJcSuHEQ_yLvVzhg',
authDomain: 'manager-2714d.firebaseapp.com',
databaseURL: 'https://manager-2714d.firebaseio.com',
projectId: 'manager-2714d',
storageBucket: 'manager-2714d.appspot.com',
messagingSenderId: '191493388327'
};
firebase.initializeApp(config);
}
render() {
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
return (
<Provider store={store}>
<LoginForm />
</Provider>
);
}
}
export default App;
答案 0 :(得分:1)
这里的问题是文件app.js未正确保存,因为github repo中的以下代码证明该文件不包含使该代码有效的thunk元素:
render() {
return (
<Provider store={createStore(reducers)}>
<LoginForm />
</Provider>
);
}
}
export default App;
同一文件中的代码是:
render() {
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
return (
<Provider store={store}>
<LoginForm />
</Provider>
);
}
}
export default App;
正确保存文件解决了问题。