【发布时间】:2020-06-13 04:38:50
【问题描述】:
我正在学习一个教程,老师在课堂上使用react-redux。为了更好地理解它,我决定使用钩子。
很遗憾,我遇到了一个问题,需要您的帮助。
教程应用使用 oauth 在 gapi 中登录。为此,使用了一个按钮,根据授权状态显示,可以登录或注销。登录时,可以在弹出窗口中选择一个谷歌帐户。 但是当我点击这个按钮登录时,我得到一个错误,上面写着:
错误:动作必须是普通对象。使用自定义中间件进行异步操作。
1) 但在我的应用程序中,我使用名为 useEffect() 的钩子和 .then 来省略使用像 thunk 这样的中间件。还是我错了?
2) 我应该在我的应用程序中使用useEffect() 和useDispatch() 还是可以使用useSelector()(或/和useDispatch(),或/和useEffect())完成所有操作
3) 教程代码使用{ connect },相当于useSelector()。我没有使用不必要的useDispatch() 和/或useEffect()?如果是,那么我怎么能在没有调度的情况下更改按钮的文本?
这里是教程代码:
import React from 'react';
import { connect } from 'react-redux';
import { signIn, signOut } from '../actions';
class GoogleAuth extends React.Component {
componentDidMount() {
window.gapi.load('client:auth2', () => {
window.gapi.client
.init({
clientId:
'797401886567-9cumct9mrt3v2va409rasa7fa6fq02hh.apps.googleusercontent.com',
scope: 'email'
})
.then(() => {
this.auth = window.gapi.auth2.getAuthInstance();
this.onAuthChange(this.auth.isSignedIn.get());
this.auth.isSignedIn.listen(this.onAuthChange);
});
});
}
onAuthChange = isSignedIn => {
if (isSignedIn) {
this.props.signIn(this.auth.currentUser.get().getId());
} else {
this.props.signOut();
}
};
onSignInClick = () => {
this.auth.signIn();
};
onSignOutClick = () => {
this.auth.signOut();
};
renderAuthButton() {
if (this.props.isSignedIn === null) {
return null;
} else if (this.props.isSignedIn) {
return (
<button onClick={this.onSignOutClick} className="ui red google button">
<i className="google icon" />
Sign Out
</button>
);
} else {
return (
<button onClick={this.onSignInClick} className="ui red google button">
<i className="google icon" />
Sign In with Google
</button>
);
}
}
render() {
return <div>{this.renderAuthButton()}</div>;
}
}
const mapStateToProps = state => {
return { isSignedIn: state.auth.isSignedIn };
};
export default connect(
mapStateToProps,
{ signIn, signOut }
)(GoogleAuth);
还有我的代码:
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { signIn, signOut } from "../actions";
const API_KEY = process.env.REACT_APP_API_KEY;
const GoogleAuth = () => {
const isSignedIn = useSelector((state) => state.auth.isSignedIn);
console.log("IsSignedIn useSelector: " + isSignedIn);
const dispatch = useDispatch();
useEffect(
() => {
const onAuthChange = () => {
if (isSignedIn) {
dispatch(signIn(window.gapi.auth2.getAuthInstance().currentUser.get().getId()));
} else {
dispatch(signOut());
}
};
window.gapi.load("client:auth2", () => {
window.gapi.client
.init({
clientId: API_KEY,
scope: "email"
})
.then(() => {
onAuthChange(window.gapi.auth2.getAuthInstance().isSignedIn.get());
console.log("isSignedIn.get(): " + window.gapi.auth2.getAuthInstance().isSignedIn.get());
window.gapi.auth2.getAuthInstance().isSignedIn.listen(onAuthChange);
});
});
},
[ dispatch, isSignedIn ]
);
const onSignInOnClick = () => {
dispatch(window.gapi.auth2.getAuthInstance().signIn());
};
const onSignOutOnClick = () => {
dispatch(window.gapi.auth2.getAuthInstance().signOut());
};
const renderAuthButton = () => {
if (isSignedIn === null) {
return null;
} else if (isSignedIn) {
return (
<button onClick={onSignOutOnClick} className="ui red google button">
<i className="google icon" />
Sign Out
</button>
);
} else {
return (
<button onClick={onSignInOnClick} className="ui red google button">
<i className="google icon" />
Sign In with Google
</button>
);
}
};
return <div>{renderAuthButton()}</div>;
};
export default GoogleAuth;
【问题讨论】:
标签: redux oauth oauth-2.0 react-redux react-hooks