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>
Related
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!
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
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!
It seems like react router does not work with redux, clicking the link in App component successfuly add '/search' to the URL but it does not navigate to the search page, the navigation only happens after i refresh the page not after clicking the link, so what is the problem here??
Here are my two components
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import * as BooksAPI from './BooksAPI';
import registerServiceWorker from './registerServiceWorker';
import { createStore, applyMiddleware } from 'redux';
import { bookReducer } from './reducers/BookReducer';
import thunk from 'redux-thunk';
import {BrowserRouter as Router} from 'react-router-dom';
const middleware = [thunk];
const store = createStore(bookReducer, [], applyMiddleware(...middleware));
ReactDOM.render(
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
App.js
import React, { Component } from 'react';
import { connect} from 'react-redux'
import BookShelf from './components/BookShelf'
import AllShelves from './components/AllShelves'
import Header from './components/Header';
import SearchPage from './components/SearchPage';
import * as BooksAPI from './BooksAPI';
import { Route } from 'react-router-dom';
import { Link } from 'react-router-dom';
import './App.css';
class App extends Component {
componentWillMount() {
this.props.fetchBooks();
}
render() {
console.log(this.props.books)
return (
<div className="App">
<Header />
<Route exact path="/" render={(props) => <AllShelves />} />
<Route path="/search" render={(props) => <SearchPage />} />
<div className="open-search">
<Link to="/search" />
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
books: state
}
}
const mapDispatchToProps = (dispatch) => {
return {
fetchBooks: () => {
BooksAPI.getAll().then(books => dispatch({
type: 'FETCH_BOOKS',
books
}))
},
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
So why clicking link doesn't cause navigation to the search page and only add '/search' to the URL.
You might need to apply withRouter to make it work.
import {withRouter , BrowserRouter as Router} from 'react-router-dom';
// your code here
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));
I recommend to to read the official documentation on how to integrate React Router with Redux
https://reacttraining.com/react-router/web/guides/redux-integration
I am trying to render a specific component inside of another component based on React, React-Router v4, and Redux in my main 'panel' wrapped in a fixed header and sidebar component.
For example when I select an item from the sidebar, I to render the Detail panel and and load the details based on the id, like: <Route path='/item/:id' component={ItemDetail} />
routes.js
import React, { Component } from 'react';
import { RouteHandler, Switch, Route, DefaultRoute } from 'react-router';
import App from './containers/App';
import Login from './containers/Login';
import LobbyDetail from './components/LobbyDetail';
export default (
<Switch>
<Route exact path="/" component={App} />
<Route exact path="/login" component={Login} />
</Switch>
);
app.js:
import React, { Component } from 'react'
import { Router, Route, Link } from 'react-router'
import { connect } from 'react-redux'
import PropTypes from 'prop-types';
import auth from '../actions/auth';
import Sidebar from '../Components/Sidebar'
class App extends Component {
static propTypes = {
};
/**
*
*/
render() {
const { ... } = this.props
return (
<div className="container-fluid">
<div className="row">
{* I WANT TO RENDER DYNAMIC COMPONENT HERE *}
</div>
<Sidebar currentUser={currentUser}
logout={logout}
/>
</div>
);
}
}
// ...
export default connect(mapStateToProps, mapDispatchToProps)(App)
index.js (basically main app):
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { createMemoryHistory } from 'history';
import routes from './routes';
import configureStore from './store/store.js';
import { AppContainer } from 'react-hot-loader';
const syncHistoryWithStore = (store, history) => {
const { routing } = store.getState();
if (routing && routing.location) {
history.replace(routing.location);
}
};
const initialState = {};
const routerHistory = createMemoryHistory();
const store = configureStore(initialState, routerHistory);
syncHistoryWithStore(store, routerHistory);
const rootElement = document.querySelector(document.currentScript.getAttribute('data-container'));
const render = () => {
ReactDOM.render(
<AppContainer>
<Provider store={store}>
<ConnectedRouter history={routerHistory}>
{routes}
</ConnectedRouter>
</Provider>
</AppContainer>,
rootElement
);
}
render();
if (module.hot) { module.hot.accept(render); }
What you're looking for is parameterized routing. Make a <Route/> like the following: <Route path='/item/:id' component={ MyComponent } />.
Now in MyComponent you can use the value of props.match.params.id to conditionally render, or if you're trying to load async data based on the value of :id; You can use the componentWillReceiveProps life cycle method and dispatch an action based on the value of this.props.match.params.id.
Note: <Link to='/item/some-item'/> will set the value of match.params.id to 'some-item'.