我试图将 firebase 引入我的 react-redux 应用程序。 我的教程不在 Ducks 中,我很难找到 Ducks 模型 react-redux-authentification 示例。
这是我使用的教程:https://blog.logrocket.com/getting-started-react-redux-firebase/ github:https://github.com/GoZaddy/react-redux-firebase-article/blob/master/src/index.js
App.js
import React, { Suspense } from 'react';
import { BrowserRouter as Router,Switch, Route} from 'react-router-dom';
import Top from './components/Top';
import Contact from './components/Contact';
import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import SignOut from './components/SignOut';
import { ConnectedRouter } from 'connected-react-router';
import {history} from './configureStore';
import { useDispatch, useSelector } from 'react-redux';
import { ReactReduxFirebaseProvider } from "react-redux-firebase";
const App = () => {
const auth = useSelector(state => state.auth);
const dispatch = useDispatch(); //Login.jsのreducerを使うため
return (
<React.Fragment>
<ReactReduxFirebaseProvider {...auth}>
<ConnectedRouter history={history}>
<Switch>
<Route exact path="/" component={Top}/>
</Switch>
<Switch>
<Route exact path="/contact" component={Contact}/>
</Switch>
<Switch>
<Route exact path="/signup" component={SignUp}/>
</Switch>
<Switch>
<Route exact path="/signin" component={SignIn}/>
</Switch>
<Switch>
<Route exact path="/signout" component={SignOut}/>
</Switch>
<Switch>
<Route exact path="/top" component={Top}/>
</Switch>
</ConnectedRouter>
</ReactReduxFirebaseProvider>
</React.Fragment>
)
}
export default App;
index.js
import ReactDOM from 'react-dom';
import App from './App'
import { Provider } from 'react-redux';
import {configureStore} from './configureStore';
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import { useHistory } from "react-router-dom";
import { useDispatch, useSelector } from 'react-redux';
import { createFirestoreInstance } from "redux-firestore";
import { BrowserRouter } from "react-router-dom";
const firebaseConfig = {
apiKey: "AIzaSyAOSBfTj_VQ4byWAAOWDhAsklmZtk2W_iE",
authDomain: "stresstackle-599d9.firebaseapp.com",
projectId: "stresstackle-599d9",
storageBucket: "stresstackle-599d9.appspot.com",
messagingSenderId: "930013144401",
appId: "1:930013144401:web:79b25db79f4118359fdf70",
measurementId: "G-J26Y6MYWV3"
};
firebase.initializeApp(firebaseConfig);
firebase.firestore();
ReactDOM.render(
<React.StrictMode>
<Provider store={configureStore()}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
rootReducers.js
import { connectRouter } from 'connected-react-router';
import {firebaseReducer} from "react-redux-firebase";
import {firestoreReducer} from "redux-firestore";
import googleAuth from './modules/googleAuth';
export const rootReducer = history => combineReducers({
router: connectRouter(history),
firebase: firebaseReducer,
firestore: firestoreReducer,
auth: googleAuth,
});
//history:履歴管理に必要なもの
//connected-react-router:reduxとつなげられる
//..>..>..>みたいなアプリ上での遷移に対応できる
// title: Consultation,
// inquiry: Consultation
configureStore.js
import { routerMiddleware } from 'connected-react-router';
import {rootReducer} from './rootReducer';
// import thunk from 'redux-thunk';
// import logger from 'redux-logger';
const createBrowserHistory = require('history').createBrowserHistory;
export const history = createBrowserHistory();
//これをApp.jsに渡した
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export function configureStore(preloadedState) {
const store = createStore(
rootReducer(history),
preloadedState,
composeEnhancers(
applyMiddleware(
routerMiddleware( history),
)
)
);
return store;
};
//↑Redux dev toolsとconnectingしている
src/modules/googleAuth.js
const initialState = {
useProfile: null,
useFirestoreForPeople: true,
}
export default function reducer(state=initialState, action) {
console.log(action);
switch (action.type){
case USE_PROFILE:
return {
...state,
useProfile: null,
useFirestoreForPeople: true,
};
default: return state
}
}
登录.js
import React, { useState } from 'react';
import { useFirebaseApp } from 'reactfire';
import 'firebase/auth'
import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import Header from './BasicComponents/Header';
import Footer from './BasicComponents/Footer';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import { StylesProvider } from "@material-ui/core/styles";
import styled from "styled-components";
import { useFirebase } from "react-redux-firebase";
import { useHistory } from "react-router-dom";
import { useDispatch, useSelector } from 'react-redux';
import { push } from 'connected-react-router'
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
textAlign: 'center',
backgroundColor: '#C0C0C0',
opacity: 0.7,
borderRadius: 50,
height: 500,
paddingTop: 20,
},
grid: {
position: 'block',
margin: '0 auto',
marginTop: 50,
marginBottom: 50,
},
input:{
width: '70%',
height: 50,
fontSize: 15,
padding: '.3em',
borderRadius: 10,
border: '1px solid #aaa',
},
input1:{
width: '70%',
height: 50,
fontSize: 15,
padding: '.1em',
marginRight: 5,
borderRadius: 10,
border: '1px solid #aaa',
},
p1:{
textAlign: 'left',
paddingLeft: 80,
fontColor: 'black',
},
button1:{
backgroundColor: 'pink',
color: 'black',
width: '35%',
borderRadius:40,
marginTop: 10,
},
button2:{
backgroundColor: '#9400D3',
color: 'black',
width: '35%',
borderRadius:40,
},
}));
export default function SignUp() {
const classes = useStyles();
const auth = useSelector(state => state.auth); //global stateを呼び出すため,Dev toolをみて決めてる
const dispatch = useDispatch();
const firebase = useFirebase();
const signInWithGoogle = () => {
firebase
.login({
provider: "google",
type: "popup",
})
.then(() => {
dispatch({ type: "USE_PROFILE" });
dispatch(push('/top'));
});
};
return (
<div className={classes.root}>
<Header/>
<Grid >
<Grid item xs={5} className={classes.grid}>
<Paper className={classes.paper}>
<form>
<h1>Welcome back!</h1>
<p>Please sign in below to continue</p>
<p className={classes.p1}>Email address</p>
<input
type="text"
name="Email"
className={classes.input1}
/><br></br>
<p className={classes.p1}>Password</p>
<input
type="password"
name="password"
className={classes.input}
/><br></br>
<Button classes={{root: classes.button1,}} type="submit">
Sign in
</Button>
<p>or</p>
<Button classes={{root: classes.button2,}}
onClick={(event) => {
event.preventDefault();
signInWithGoogle();
}} >
Sign in with Gmail
</Button><br></br>
<p >Forgot Password?</p>
</form>
</Paper>
</Grid>
</Grid>
<Footer/>
</div>
);
}