Is it possible to use more reducer in app - reactjs

Is it possible to use more reducer in app, I have created several reducer files and I want to share in provider. Is it possible? I tried not many things but without success, like for example: combineReducers.
import { BrowserRouter, Routes, Route} from 'react-router-dom';
import { createStore, combineReducers} from "redux";
//import reducer from "../src/reducer/TestReducer";
import reducerAuthentification from "../src/reducer/ReducerAuthentification"
import TestReducer from "../src/reducer/TestReducer"
import './assets/style/app/App.css';
import './assets/style/app/App.scss';
import React from 'react';
import Accueil from './view/accueil/Accueil';
import Feuillete from './view/patisserie/Feuilletes';
import Footer from './view/footer/Footer';
import Reservation from './view/reservation/Reservation';
import { Provider } from 'react-redux';
import Compte from './view/client/compte/Compte';
const store = createStore(reducerAuthentification);
const store1 = createStore(TestReducer)
// const appReducers = createStore({
// reducerAuthentification: "",
// TestReducer: ""
// })
function App() {
return (
<Provider store={{store}}>
<div className="App">
<BrowserRouter>
{/* <Navbar/> */}
<header className="App-header">
<Navigation/>
</header>
<Routes>
<Route path={"/"} element={<Accueil />}/>
<Route path={"/les-patisseries/les-feuilletes"} element={<Feuillete />}/>
<Route path={"/reservation"} element={<Reservation />}/>
<Route path={"/compte"} element={<Compte />} />
</Routes>
<Footer />
</BrowserRouter>
</div>
</Provider>
);
}
export default App;

Best practice is to combine all reducer in separate file.
For example:
rootReducer.js:
const rootReducer = combineReducers({
reducer1: reducerOne,
reducer2: reducerTwo,
})
export default rootReducer
store.js:
import rootReducer from './rootReducer'
const store = createStore(rootReducer)
Redux createStore is depreceated method, it works but you should use configureStore for creating store.
See: https://redux-toolkit.js.org/introduction/getting-started

You can use combineReducers as shown in their documentation.
https://redux.js.org/api/combinereducers

Related

React application is not working with store, reducer and provider import

In my react application, I created store.js and rootreducer.js for it. Before creating the store.js and rootreducer.js file, my react application was working properly but after adding it, I'm actually not getting any error but my output on the local host is blank now. For including the store and reducer in my application I have imported the provider and store to my app.js file. If I remove them, my react application works properly but with these imports, I get a blank screen in my localhost. Below given is my store.js file
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './Reducer/rootReducer';
const initialState = {}
const middleWare = [thunk]
let store;
if (window.navigator.userAgent.includes("Chrome")) {
store = createStore(rootReducer,
initialState,
compose(applyMiddleware(...middleWare),
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
))
} else {
store = createStore(rootReducer,
initialState,
compose(applyMiddleware(...middleWare)))
}
export default store;
And this is my app.js file
import React from 'react';
import './App.css';
import Nav from './Component/Common/Nav';
import 'bootstrap/dist/css/bootstrap.css';
import Welcome from './Component/Welcome';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Dashboard from './Component/Dashboard/Dashboard';
import CreateMonthWallet from './Component/Dashboard/DashboardOperations/CreateMonthWallet';
import NotFound from './Component/Common/NotFound';
import { Provider } from 'react-redux';
import store from './Store';
//import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
function App() {
return (
<Provider store={store}>
<Router>
<div>
<Nav />
<Routes>
<Route path="/" element={<Welcome />} exact />
<Route path="/Dashboard" element={<Dashboard />} exact />
<Route path="/CreateMonthWallet" element={<CreateMonthWallet />} exact />
<Route path="*" element={<NotFound />} exact />
</Routes>
</div>
</Router>
</Provider>
);
}
export default App;
And this is my rootreducer.js file
import {combineReducers} from 'redux'
export default combineReducers({
});
you can add your store like this in app.js
your code
import store from './Store';
add this
import {store} from './Store';
hope this will help you!

ReactDOM doesn't render the app, even though application 'compiles sucessfully'

I have encountered a problem with th fact that reactDOM.render doesnt render the app despite yarn run compiling sucessfully.
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {Provider} from 'react-redux';
import {PersistGate} from 'redux-persist/integration/react';
import {store ,persistor} from './redux/store.js'
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Redux configuration in store.js
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import {persistStore} from 'redux-persist';
import createSagaMiddleware from 'redux-saga';
import { fetchGalleryStart } from './gallery/gallery.saga';
import {rootReducer} from './root.reducer.js';
const sagaMiddleware= createSagaMiddleware();
const middlewares = [sagaMiddleware];
if (process.env.NODE_ENV==='development') {
middlewares.push(logger)
}
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
sagaMiddleware.run(fetchGalleryStart); //inside run we pass each individual saga
const exportedObject = {
store,
persistor,
};
export default exportedObject;
The app.js
import React from 'react';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Header from './components/header/header.component.jsx';
import Footer from './components/footer/footer.component.jsx';
import HomePage from './pages/homepage/homepage.component.jsx';
import Contact from './pages/contact/contact.component.jsx';
import About from './pages/about/about.component.jsx';
class App extends React.Component {
render () {
return (
<div className="App">
<BrowserRouter>
<Header />
<div className="wrapper">
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/contact" component={Contact} />
<Route path="/about" component={About} />
<Route path="*">error</Route>
</Switch>
</div>
<Footer/>
</BrowserRouter>
</div>
);
}
};
export default App
When I open the app in the browser, the app is not rendered on the root, page stays blank.
Could you please help me where to look? I am pretty lost how to approach this since i receive no error.
Thank you for your time
Wrap your render()... method with a class component like this:
class App extends React.Component {
render() {
return ();
}
}
export default App;
To declare App correct.
Or get rid of render() method and do a function:
funciton App() => {
return (<div></div>);
}
export default App;
Hope I could help you and have fun!

React-redux, can't use connect with my root component

I can't use connect, with export in App component. No error is thrown, the app starts normally... but all my links in my navbar stop to work (???). The url changes, but the main page is always displayed, like it would break the routing. Here is my code:
import { Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import Layout from './hoc/Layout/Layout';
import BurgerBuilder from './containers/BurgerBuilder/BurgerBuilder';
import Checkout from './containers/Checkout/Checkout';
import Orders from './containers/Orders/Orders';
import Auth from './containers/Auth/Auth';
import * as actions from './store/actions'
class App extends Component {
render () {
return (
<div>
<Layout>
<Switch>
<Route path="/checkout" component={Checkout} />
<Route path="/orders" component={Orders} />
<Route path="/auth" component={Auth} />
<Route path="/" exact component={BurgerBuilder} />
</Switch>
</Layout>
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
anything: ()=>dispatch(actions.logout())
}
};
export default connect(null, mapDispatchToProps)(App);
//export default App;
If I comment the 'connect' part, like this:
//export default connect(null, mapDispatchToProps)(App);
export default App;
everything runs ok and all my links are working fine. Why can't I use 'connect' in my App component? I know I'm not dispatching any actions through props, but it should work nontheless, as far as I'm concerned.
Below is my index.js file, which uses th App component:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import burgerBuilderReducer from './store/reducers/burgerBuilder';
import orderReducer from './store/reducers/order';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const rootReducer = combineReducers({
burgerBuilder: burgerBuilderReducer,
order: orderReducer
});
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk)
));
const app = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
ReactDOM.render( app, document.getElementById( 'root' ) );
registerServiceWorker();
I think the problem is your mapDispatchToProps:
import {bindActionCreators} from 'redux'
...
const mapDispatchToProps = dispatch => (bindActionCreators({
actionName: () => ({type:'SOME_ACTION', payload: 'SOME_PAYLOAD'}),
doLogout: () => actions.logout(),
}, dispatch))
EDIT: Do this changes to your App.js
<BrowserRouter>
<Switch>
<Route path="/checkout" component={Checkout} />
<Route path="/orders" component={Orders} />
<Route path="/auth" component={Auth} />
<Route path="/" exact component={BurgerBuilder} />
</Switch>
</BrowserRouter>
I think I got it. The solution was to wrap both my App and Layout components (layout holds my navigation items) with "withRouter":
export default withRouter(connect(null, mapDispatchToProps)(App));
export default withRouter(connect(mapStateToProps)(Layout));

Footer renders between navbar and component instead of after the component in React-Redux

As the title says, my footer is rendering between the navbar and component while it should render after the component. I can place the footer at the bottom with CSS, but in the Chrome developer console it still renders the component after the footer.
This is how I have the app.js setup. It is using react-router-dom for client-side routing. The {this.props.children} renders the correct component based on the route: /home, /help, etc..
import React, { Component } from 'react';
import Navbar from '../containers/navbar';
import Footer from '../containers/footer';
export default class App extends Component {
render() {
return (
<div>
<Navbar />
{this.props.children}
<Footer />
</div>
);
}
}
EDIT: This is what I ended up doing per suggestion in comments:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { routerMiddleware, ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import App from './components/app';
import Navbar from './containers/navbar';
import Footer from './containers/footer';
import Signin from './containers/authentication/signin';
import Signout from './containers/authentication/signout';
import PasswordReset from './containers/authentication/password_reset';
import UsernameRecovery from './containers/authentication/username_recovery';
import Home from './components/home';
import Help from './components/help';
import RequireAuth from './helpers/require_auth';
import LeftSite from './helpers/left_site';
import rootReducer from './reducers';
import styles from '../assets/scss/main.scss';
const history = createHistory();
const initialState = {};
const enhancers = [];
const middleware = [thunk, routerMiddleware(history)];
if (process.env.NODE_ENV === 'development') {
const devToolsExtension = window.devToolsExtension
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers);
const store = createStore(rootReducer, initialState, composedEnhancers);
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Navbar />
<App />
<Switch>
<Route exact path='/home' component={LeftSite(RequireAuth(Home))} />
<Route exact path='/help' component={LeftSite(RequireAuth(Help))} />
<Route exact path='/auth/username' component={UsernameRecovery} />
<Route exact path='/auth/password' component={PasswordReset} />
<Route exact path='/auth/signout' component={Signout} />
<Route exact path='/auth/signin' component={Signin} />
<Route exact path='/' component={Signin} />
</Switch>
<Footer />
</div>
</ConnectedRouter>
</Provider>
, document.querySelector('.container'));
Per jonahe's suggestion, I ended up moving the <Navbar /> and <Footer /> out of the app.js file where the various components were being rendered. I moved them into the main index.js where my routes are at and ended up with the following.
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { routerMiddleware, ConnectedRouter } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import App from './components/app';
import Navbar from './containers/navbar';
import Footer from './containers/footer';
import Signin from './containers/authentication/signin';
import Signout from './containers/authentication/signout';
import PasswordReset from './containers/authentication/password_reset';
import UsernameRecovery from './containers/authentication/username_recovery';
import Home from './components/home';
import Help from './components/help';
import RequireAuth from './helpers/require_auth';
import LeftSite from './helpers/left_site';
import rootReducer from './reducers';
import styles from '../assets/scss/main.scss';
const history = createHistory();
const initialState = {};
const enhancers = [];
const middleware = [thunk, routerMiddleware(history)];
if (process.env.NODE_ENV === 'development') {
const devToolsExtension = window.devToolsExtension
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers);
const store = createStore(rootReducer, initialState, composedEnhancers);
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<div>
<Navbar />
<App />
<Switch>
<Route exact path='/home' component={LeftSite(RequireAuth(Home))} />
<Route exact path='/help' component={LeftSite(RequireAuth(Help))} />
<Route exact path='/auth/username' component={UsernameRecovery} />
<Route exact path='/auth/password' component={PasswordReset} />
<Route exact path='/auth/signout' component={Signout} />
<Route exact path='/auth/signin' component={Signin} />
<Route exact path='/' component={Signin} />
</Switch>
<Footer />
</div>
</ConnectedRouter>
</Provider>
, document.querySelector('.container'));

BrowserRouter doesnt accept child routes passed as props

I am using react-router 4 with react-redux. but now I am not able to render any page. I am getting 404 while hitting URL. but console is not showing any error. may be I have colluded something with react-router version 3 but not able to get it what? one more thing here is that my one reducers is being called while store registration though I am not adding reducers in it.and more thing is IndexRoute deprecated in v4?
here is my config.js
import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware,compose } from 'redux'
import { Provider } from 'react-redux'
//import rootReducer from './reducers'
import createLogger from 'redux-logger'
import thunk from 'redux-thunk'
import {BrowserRouter} from 'react-router-dom'
import App from './containers/App'
import promise from "redux-promise-middleware"
import logger from "redux-logger"
import {fetchUsers} from "./action/UserAction"
import {fetchChart} from "./action/ChartAction"
import {fetchNames} from "./action/SearchAction"
import reducer from "./reducers"
import routes from "./routes"
const middleware = applyMiddleware(promise(), thunk, logger())
//const store= createStore(reducer,middleware)
const store= createStore(middleware)
//store.dispatch(fetchUsers());
//store.dispatch(fetchChart());
render(
<Provider store={store}>
<BrowserRouter routes={routes} />
</Provider>,
document.getElementById('root')
)
my routes.js
import App from "./pages/App"
import Users from "./pages/Users"
import Charts from "./pages/Charts"
import React from "react"
import { Route } from "react-router-dom"
export default (
<Route path="/" component={App}>
{/* <IndexRoute component={Users} /> */}
<Route path="/" component={Users}/>
<Route path="charts" name="charts" component={Charts}/>
</Route>
);
my App.js
import {Link} from "react-router"
const App = () =>(
<div>
<h1> this is main page </h1>
<Link to="charts">charts</Link>
</div>
)
export default App
my charts.js
const Chart = () => (
<h1> this is chart </h1>
)
export default Chart
my Users.js
const User = () =>(
<div>
<h1> this is user </h1>
</div>
)
export default User
and reducer is that is being called
import _intialState from "../api/names.js"
const intialValues = {names:['x','y','z','a','b','c','d','e','f'],
searchText:''}
export default function reducer(
state=intialValues,
action){
console.log("search reducer",state)
switch(action.type){
case "SEARCH":{
return Object.assign({},state,{searchText:action.payload})
}
default:
return state;
}
}
As per the react-router documentation, there is no props called routes to BrowserRouter
Instead you can specify the routes to BrowserRouter as children.
children: node
A single child element to render.
Use it like
<BrowserRouter >
{routes}
</BrowserRouter>

Resources