使用Redux在React 16中的路由已停止工作

时间:2018-02-21 04:24:04

标签: reactjs react-router react-redux

天儿真好。 我最近把我的应用程序升级到了React 16.因为它只是 写下我写的一半是个好时光。

路由已停止工作。单击菜单链接会更改浏览器栏中的URL,不会向控制台抛出任何错误,但会呈现NOTHING!

我用谷歌搜索了几天,“解决方案”有点无处不在。

有没有人说过这个。好吧,有人必须拥有。任何指向最新HOWTO的指针都将受到赞赏。

一些代码 index.js

import React                            from 'react';
import ReactDOM                         from 'react-dom';
import { Provider }                     from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxPromise                     from 'redux-promise';

import reducers                         from './reducers';

import App                              from './components/app'


const createStoreWithMiddleware =                           // this little lot looks confusing, it is 
        applyMiddleware(ReduxPromise)(createStore);         // we first creat a store ENVIRONMENT that uses
                                                            // ReduxPromise as the middleware we will use
const store = createStoreWithMiddleware(reducers);          // then create the store (where to put STATE)
module.hot.accept('./reducers', () => {                     // THEN... ReactReduc USED to magically allow
    const nextRootReducer = require('./reducers/index');    // hot reducer reloading, but that caused problems it seems.
    store.replaceReducer(nextRootReducer);                  // so we now tell webpack EXPLICITALLY that we want to
});                                                         // allow hot reloading.  See? Nossohard!

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
  , document.querySelector('#ai-container'));

app.js

import React, { Component }             from 'react';
import Header                           from '../containers/header';
import { BrowserRouter, Route, Link }   from 'react-router-dom';

import Routes                           from '../routes';

//------------------------------------------
export default class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <div>
                    <Header />
                    {Routes}
                </div>
            </BrowserRouter>
        );
    }
}

//

示例组件

import React, { Component } from 'react';
import WeatherSearchBar     from '../containers/weather_search_bar';
import WeatherList          from '../containers/weather_list';

//-----------------------------------------------
export default class Weather extends Component {
    render() {
        console.log("In Weather superClass");
        return (
            <div>
                <div className="jumbotron">
                    <h2>Asset-IQ - Live Build - April 2017</h2>
                    <h2>Five Day Weather Forecast</h2> 
                </div>
                <WeatherSearchBar       />
                <WeatherList            />
            </div>
        );
    }
}

组件内的容器。搜索栏

import React, { Component }     from 'react';
import { connect }              from 'react-redux';
import { bindActionCreators }   from 'redux';
import { apiGetExternalData }   from '../actions/api';

import { FETCH_WEATHER }        from '../actions/api';


//-----------------------------------------
class WeatherSearchBar extends Component {

    // we extend the REACT component, but this is a REDUX CONTAINER.

    //------------------
    constructor(props) {
        super(props);                                               // call the parent class constructor
        this.state = { term: '' };                                  // det initial state of this

        this.onInputChange = this.onInputChange.bind(this);         // and bind our methods to this
        this.onFormSubmit  = this.onFormSubmit.bind(this);
    }


    //--------------------
    onInputChange(event) {

        // This is a different sort of input search bar
        // to the last one published.  This one gets ONE
        // value and then does something on submit.
        // The last search bar did the 'smart' search on
        // every onChange event.  ie., raced off to consume
        // a store.

        this.setState({ [event.target.name]: event.target.value }); // this is how to write the onChange handler 
                                                                    // for forms that have multiple fields,
                                                                    // i.e. most forms.  We do not have to write a 
                                                                    // specific event handler for each.
                                                                    // Although, I think checkboxes are somehow different

    }


    //-------------------
    onFormSubmit(event) {

        const API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXX';
        const URL     = `http://api.openweathermap.org/data/2.5/forecast?appid=${API_KEY}&q=${this.state.term},AU`;

        console.log(URL);
        event.preventDefault();                                     // kill the normal POST from the browser
        this.props.apiGetExternalData(FETCH_WEATHER, URL);          // fetch some data based on the input field
        this.setState({ term: '' });                                // reset input field to empty
    }



    //--------
    render() {
        return (
            <form onSubmit={this.onFormSubmit} className="input-group search-bar-entry">
                <input 
                    placeholder="Get a five day weather forecast for a city"
                    className="form-control"
                    name="term" 
                    value={this.state.term}
                    onChange={this.onInputChange}
                />
                <span className="input-group-btn">
                    <button type="submit" className="btn btn-secondary">Search</button>
                </span>
            </form>
        );
    }
}


//-----------------------------------------------------------------
function mapDispatchToProps(dispatch) {
    return bindActionCreators( { apiGetExternalData }, dispatch);
}

//-----------------------------------------------------------------
// the null argument here indicates that we know REDUX 
// is managing STATE, but this particular bit of code
// is not interested in it.

export default connect(null, mapDispatchToProps)(WeatherSearchBar);

//------------------------- EOF  ------------------------------------------------------

添加了routes.js。控制台上没有任何错误!

import Authenticate             from './containers/client_auth';

//---------------
export default (
    <Switch>
        <Route exact path="/"                   component={Home}                            />
        <Route path="assets"                    component={Assets}                          />
        <Route path="asset_new_edit"            component={CreateEditAsset}                 />
        <Route path="asset_new_edit:asset_id"   component={CreateEditAsset}                 />
        <Route path="asset_work"                component={CreateAssetWorkflow}             />
        <Route path="asset_widget"              component={WidgetTestForm}                  />
        <Route path="asset_video"               component={AssetVideo}                      />
        <Route path="about"                     component={About}                           />
        <Route path="faq"                       component={FAQ}                             />
        <Route path="contact"                   component={Contact}                         />
        <Route path="blog"                      component={Blog}                            />
        <Route path="blog/new"                  component={BlogNew}                         />
        <Route path="blog/:id"                  component={BlogShow}                        />
        <Route path="login"                     component={Login}                           />
        <Route path="logout"                    component={Logout}                          />
        <Route path="register"                  component={Register}                        />
        <Route path="weather"                   component={Weather}                         />
        <Route path="/people"                   component={People}                          />
        <Route path="/people_new"               component={CreatePeople}                   />
        <Route path="/people/:email"            component={ShowPeople}                     />
        <Route path="/people_edit/:email"       component={EditPeople}                     />
        <Route path="organisations"             component={Organisations}                   />
        <Route path="organisation_new"          component={CreateOrganisation}              />
        <Route path="organisation/:name"        component={ShowOrganisation}                />
        <Route path="organisation_edit/:name"   component={EditOrganisation}                />
        <Route path="locations"                 component={Locations}                       />
        <Route path="location_new"              component={CreateLocation}                  />
        <Route path="location/:name"            component={ShowLocation}                    />
        <Route path="location_edit/:name"       component={EditLocation}                    />
        <Route path="roles"                     component={Roles}                           />
        <Route path="role_new"                  component={CreateRole}                      />
        <Route path="role/:name"                component={ShowRole}                        />
        <Route path="role_edit/:name"           component={EditRole}                        />
        <Route path="industries"                component={Industries}                      />
        <Route path="industry_new"              component={CreateIndustry}                  />
        <Route path="industry/:name"            component={ShowIndustry}                    />
        <Route path="industry_edit/:name"       component={EditIndustry}                    />
    </Switch>    
);

任何提示都表示赞赏! 欢呼声,

1 个答案:

答案 0 :(得分:1)

在您的路线中放置/之前,如下所示,这对我有用!!!

export default (
<Switch>
    <Route exact path="/" component={Home} />
    <Route path="/assets" component={Assets} />
    <Route path="/asset_new_edit" component={CreateEditAsset} />
    <Route path="/asset_new_edit:asset_id" component={CreateEditAsset} />
    <Route path="/asset_work" component={CreateAssetWorkflow} />
    <Route path="/asset_widget" component={WidgetTestForm} />
    <Route path="/asset_video" component={AssetVideo} />
    <Route path="/about" component={About} />
    <Route path="/faq" component={FAQ} />
    <Route path="/contact" component={Contact} />
    <Route path="/blog" component={Blog} />
    <Route path="/blog/new" component={BlogNew} />
    <Route path="/blog/:id" component={BlogShow} />
    <Route path="/login" component={Login} />
    <Route path="/logout" component={Logout} />
    <Route path="/register" component={Register} />
    <Route path="/weather" component={Weather} />
    <Route path="/people" component={People} />
    <Route path="/people_new" component={CreatePeople} />
    <Route path="/people/:email" component={ShowPeople} />
    <Route path="/people_edit/:email" component={EditPeople} />
    <Route path="/organisations" component={Organisations} />
    <Route path="/organisation_new" component={CreateOrganisation} />
    <Route path="/organisation/:name" component={ShowOrganisation} />
    <Route path="/organisation_edit/:name" component={EditOrganisation} />
    <Route path="/locations" component={Locations} />
    <Route path="/location_new" component={CreateLocation} />
    <Route path="/location/:name" component={ShowLocation} />
    <Route path="/location_edit/:name" component={EditLocation} />
    <Route path="/roles" component={Roles} />
    <Route path="/role_new" component={CreateRole} />
    <Route path="/role/:name" component={ShowRole} />
    <Route path="/role_edit/:name" component={EditRole} />
    <Route path="/industries" component={Industries} />
    <Route path="/industry_new" component={CreateIndustry} />
    <Route path="/industry/:name" component={ShowIndustry} />
    <Route path="/industry_edit/:name" component={EditIndustry} />
</Switch>