Having Problems with React Router v4 / Mobx - reactjs

I can't get my routing to work when I click on my button nothing happens. I am using mobx-react-router
import plannerStore from './PlannerStore';
import { RouterStore } from 'mobx-react-router';
const routingStore = new RouterStore();
const stores = {
plannerStore,
routingStore
}
export default stores;
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'mobx-react';
import { useStrict } from 'mobx';
import createBrowserHistory from 'history/createBrowserHistory';
import { syncHistoryWithStore } from 'mobx-react-router';
import { Router } from 'react-router';
import App from './App';
import PlannerComponent from './components/PlannerComponent';
const browserHistory = createBrowserHistory();
import stores from './stores/index';
const history = syncHistoryWithStore(browserHistory, stores.routingStore);
useStrict(true);
ReactDOM.render(
<Provider {...stores}>
<Router history={history}>
<PlannerComponent />
</Router>
</Provider>,
document.getElementById('root')
);
import React, {Component} from 'react'
import ReactDOM from 'react-dom';
import {observer, inject} from 'mobx-react';
import CourseComponent from './CourseComponent';
import GradeComponent from './GradeComponent'
import { Route } from 'react-router';
#inject('plannerStore', 'routingStore')
#observer
export default class PlannerComponent extends Component {
constructor() {
super();
}
render() {
return (
<div>
<CourseComponent />
<Route path='/grade' component={GradeComponent}/>
</div>
)
}
}
import React, {Component} from 'react'
import ReactDOM from 'react-dom';
import {observer, inject} from 'mobx-react';
import planner from '../styles/planner.scss'
#inject('plannerStore', 'routingStore')
#observer
export default class CourseComponent extends Component {
constructor() {
super();
}
render() {
const { location, push, goBack } = this.props.routingStore;
return (
<div >
<button onClick={() => push('/grade')}>grades</button>
</div>
)
}
}

It is because #observer is optimizing shouldComponentUpdate, and prevents your component from updating. You can wrap a component with the withRouter higher-order component and it will be given the current location as one of its props, so the Route will know that the location changed.
You can read more here: React Router Docs

Try to inject the routingStore in a component containing the Router component instead if the PlannerComponent, something like this:
#inject("routingStore")
#observer
class AppContainer extends Component {
render() {
return (
<Router history={history}>
<PlannerComponent />
</Router>
);
}
}
and then:
ReactDOM.render(
<Provider {...stores}>
<AppContainer/>
</Provider>,
document.getElementById('root')
);

Related

Changing url without displaying the page

There is a problem navigating to the application page. When clicked, the url changes, but the content does not change. Wrapped connect in withRouter but doesn't help. I'm using webpack 5, but I haven't configured anything for routing. Where could the problem be with this implementation?
App.js
import logo from './logo.svg';
import history from "./utils/history";
import './App.css';
import AuthLayout from "./containers/auth-controller";
import Menu from './components/menu';
import {
Router,
Switch,
Route
} from "react-router-dom";
import routes from './routes'
function App() {
return (
<Router history={history}>
<AuthLayout>
<div className="App">
<Menu/>
<div className="page">
{routes}
</div>
</div>
</AuthLayout>
</Router>
);
}
export default App;
index.js
import history from "./utils/history";
let React = require('react');
let ReactDOM = require('react-dom');
import './index.css';
import 'antd/dist/antd.css';
import App from './App';
import {Provider} from "react-redux";
import store from "./store";
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<Provider store={store}>
<React.StrictMode>
<App/>
</React.StrictMode>
</Provider>,
document.getElementById('root')
);
Route.js
import React from 'react';
import { withRouter } from 'react-router-dom';
import { Route } from 'react-router-dom';
import Component from './component';
export default <Route exact path="/tests" component={Component} />;
Routes.js
import React from 'react';
import { Switch, Redirect } from 'react-router-dom';
import * as Pages from './pages';
export default (
<Switch>
{ Object.values(Pages) }
</Switch>
);
component.js
import React from 'react';
import {connect} from "react-redux";
import {withRouter} from "react-router-dom";
import history from "./history";
class Component extends React.Component {
state = {
username: undefined,
password: undefined
}
onRedirect = () => {
history.push("/home");
}
render() {
const {token} = this.props;
return (
<div className="auth">
<a onClick={this.onRedirect}>Redirect</a>
</div>
)
}
}
function mstp(state) {
return {
...
}
};
function mdtp(dispatch) {
return {
...
}
}
}
export default withRouter(connect(mstp, mdtp)(Component));
export default withRouter(connect(mstp, mdtp)(Component));
history.js
import { createBrowserHistory } from 'history';
export default createBrowserHistory();

How to get ReactRouter Props , while using Redux

App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
// import browserRoute
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom'
// redux
import Todo from './todo/Todo';
import Login from './todo/Login';
import Home from './todo/Home';
import Callender from './Callender/Callender'
import WhetherData from './Callender/CallenderComponent'
import { localstoreExport } from './index';
export default class App extends Component {
render() {
return (
<BrowserRouter>
< Switch>
<Route path="/todo">
<Todo />
</Route>
<Route path="/login">
<Login />
</Route>
<Route path ="/callender">
<Callender />
</Route>
<Route path="/climateshow" component ={WhetherData}/>
<Route exact path="/" component={Home}/>
</Switch>
</BrowserRouter>
</Provider>
)
}
}
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
// Redux
import { createStore,combineReducers,applyMiddleware,compose } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
// import reducer
import todoReducer from './store/reducers/rootReducer';
import whetherReducer from './store/reducers/callender'
// combine the Reducer
const rootReducer = combineReducers({
todoReducer,
whetherReducer
})
// chrome extension helper
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// create a store
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));
export const localstoreExport = store;
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementById('root'));
Callender.js
import React, { Component } from 'react';
import { DatePicker, DatePickerInput } from 'rc-datepicker';
import 'rc-datepicker/lib/style.css';
import axios from 'axios'
import { connect } from 'react-redux';
// redux components
import { getDataFromApi } from '../store/actions/callender'
class Callender extends Component {
state = {
totalDate:''
}
// These is the complete code for getting the response from version 2 of api
onChange = (event) =>{
console.log(event);
this.setState({
totalDate:event
})
this.props.getWhetherData()
{console.log(this.props.whetherData)}
}
render() {
const date = '2015-06-26';
return (
<div>
<DatePicker onChange={this.onChange} value={date} />
{this.props.whetherData? console.log(this.props.history): null}
</div>
)
}
}
const mapStateToProps = state =>{
return {
whetherData: state.whetherReducer.whetherData
}
}
const mapDispatchToProps = dispatch =>{
return {
getWhetherData : () => dispatch(getDataFromApi())
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Callender);
1)In the following code I have written my Routes, in App.js file and created store in Index.js
2) In Callender.js i want to push my route to whether data end Point so i am trying to see the this.props.history it is showing undefined
3) so i tried to see my props by this.props Now it is showing me the redux props so i realized that
my router props are getting overridden by redux props
4) how to use history push while using redux
You can wrap your component with withRouter.
import { withRouter } from "react-router";
export default connect(mapStateToProps,mapDispatchToProps)(withRouter(Callender));
You can find detailed example here.

Why react router does not work with redux?

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 have an error with browserHistory and react-router

Someone can help me please, I want to use react router but, but I have an error that I can not fix .
My error is : 'react-router' does not contain an export named 'browserHistory'.
My code Below
Thanks ^^
import React, { Component } from 'react'
import {Router, Route, Link,browserHistory,IndexRoute} from 'react-router'
import PostList from './containers/post_list'
class Routes extends Component {
render () {
return (
<div>
<Router history={browserHistory}>
<Route path="/" component={PostList}/>
</Router>
</div>
)
}
}
export default Routes
import React, { Component } from 'react'
class PostList extends Component {
render () {
return (
<div>
<h1>Liste des posts</h1>
</div>
)
}
}
export default PostList;
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import Routes from './routes.js';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware()(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Routes/>
</Provider>
, document.querySelector('.container'));
React-Router v4 does not contain browserHistory.
Either downgrade to v3 or rewrite things to use v4.
See e.g. https://github.com/ReactTraining/react-router/issues/4732
Thanks AKX ^^
The right way below
import React, { Component } from 'react'
import { BrowserRouter, Route} from 'react-router-dom'
import PostList from './containers/post_list';
class Routes extends Component {
render () {
return (
<BrowserRouter>
<Route path="/new" component={PostList}/>
</BrowserRouter>
)
}
}
export default Routes

Could not find "store" in either the context or props of "Connect(App)".

I am new to React Js.
Everything works fine until I am trying to do action creator in ReactJs.
I know that there are other questions(posts) related to the title,however , I cannot find to solve my problem. Please Help me!
Here is my index.js
import 'materialize-css/dist/css/materialize.min.css';
import React from 'react';
import ReactDOM from 'react-dom';
import { provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reduxThunk from 'redux-thunk';
import App from './components/App';
import reducers from './reducers';
import connect from 'react-redux/lib/connect/connect';
// create reducer
const store = createStore(reducers, {}, applyMiddleware(reduxThunk));
// Render the App in the HTML root element which is inside public foler
ReactDOM.render(
//Provier is to handle redux store actions
<provider store = { store }><App/></provider> ,
document.querySelector('#root')
);
Here is my App.Js
import React,{ Component } from 'react';
import { BrowserRouter, Route} from 'react-router-dom';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Header from './Header';
const dashboard = () => <h2>DashBoard</h2>
const surveyNew = () => <h2>SurveyNew</h2>
const landing = () => <h2>Landing</h2>
class App extends Component {
//Call Action Creaters before View is Up
componentDidMount() {
this.props.fetchUser();
}
render () {
return (
<div className="container">
<BrowserRouter>
<div>
<Header/>
<Route exact path="/" component = {landing} />
<Route exact path = "/surveys" component = {dashboard}/>
<Route path = "/surveys/new" component = {surveyNew} />
</div>
</BrowserRouter>
</div>
);
}
};
export default connect(null, actions)(App);
Any help would be appreciated, Sirs. Thank You
It is with a capital "p" in "Provider". Try like that:
import { Provider } from 'react-redux';
...
<Provider store={store}><App/></Provider> ,

Resources