react-router-dom链接在app.js(父组件)中起作用,但在子组件中不起作用

问题描述 投票:2回答:2

我在'app.js'(父组件)中有'导航'组件,而'home.js'有条件地仅在主页中通过设置header { height: 90vh }在页眉底部响应空白。

为了做到这一点,我在'Home.js'的头标记中包含了<Nav>。

问题出现了,Nav Link在app.js中工作得很好,但在home.js中甚至无法点击。

Homepage Header Image

index.js

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter as Router } from 'react-router-redux';
import createHistory from 'history/createBrowserHistory';
import Store from './Store';
import Routes from './Routes';

require('./styles/main.scss');

const root = document.createElement('div');
document.body.appendChild(root);

render(
  <Provider store={Store}>
    <Router history={createHistory()}>
      <Routes />
    </Router>
  </Provider>,
  root,
);

Routes.js

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { hot } from 'react-hot-loader';
import App from './src/app';
/* --- Components --- */
import Loader from './src/shared/loader';

const Home = Loader({
      loader: () => import('./src/components/Home' /* webpackChunkName: 'Home' */),
    });

const Login = Loader({
      loader: () => import('./src/components/login' /* webpackChunkName: 'Login' */),
    });

const NoMatch = Loader({
      loader: () => import('./src/shared/NoMatch' /* webpackChunkName: 'NoMatch' */),
    });

const routes = () => (
      <div>
        <App />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/login" component={Login} />
          <Route component={NoMatch} />
        </Switch>
      </div>
    );

const Routes =
      !module.hot || process.env.NODE_ENV === 'production'
        ? routes
        : hot(module)(routes);

export default Routes;

App.js

import React from 'react';
import { Helmet } from 'react-helmet';
/* --- shared --- */
import Loader from './shared/loader';

const Nav = Loader({
  loader: () => import('./shared/nav' /* webpackChunkName: 'Nav' */),
});

const App = props => {
  const isHomepage = window.location.pathname === '/';

  return (
    <div id="app">
      <Helmet>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>###</title>
        <meta property="og:title" content="###" />
        <meta property="og:description" content="###" />
        <meta property="og:type" content="###" />
        <meta property="og:url" content="###" />
        <meta property="og:image" content="###" />
        <link type="text/plain" rel="author" href="http://domain/humans.txt" />
        <link type="text/plain" rel="author" href="http://domain/robots.txt" />
        <link
          href="https://fonts.googleapis.com/css?family=Nanum+Gothic"
          rel="stylesheet"
        />
        <link
          rel="stylesheet"
          href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
        />
      </Helmet>
      {props.children}
      {!isHomepage ? <Nav /> : null}
    </div>
  );
};

export default App;

nav.js

import React from 'react';
/* --- shared --- */
import * as data from './data';
import Ul from './ul';

const Nav = () => (
  <div className="nav">
    <div className="flex justify-between nav--top">
      <p className="mh-auto f-mini fw3">
        상담전화
        <span className="f-regular"> xxx&#45;xxxx&#45;xxxx</span>
      </p>
      <Ul links={data.redirectToLogin} />
    </div>
    <h1>
      <Ul links={data.redirectToHome} />
    </h1>
    <div className="hr-center">
      <Ul links={data.nav} />
    </div>
  </div>
);

export default Nav;

ul.js

import React from 'react';
import { Link } from 'react-router-dom';

const Ul = ({ links }) => (
  <ul className="nav-menu">
    {links &&
      links.map(e => (
        <li>
          <Link className={e.className} key={e.id} to={e.to}>
            {e.name}
          </Link>
        </li>
      ))}
  </ul>
);

export default Ul;

Home.js

import React from 'react';
/* --- Components --- */
import HomeMain from './Home.main';
/* --- Shared --- */
import Nav from '../shared/nav';

const Home = () => (
  <div>
    <header>
      <Nav />
      <div className="header-text--box">
        <h2>
          <span className="f-regular f-en lh-3">NO MSG!</span>
          <br />
          오늘도 열심히 일하는 당신에게 착한 가격의 집밥을 선물하세요.
        </h2>
      </div>
    </header>
    <HomeMain />
  </div>
);

export default Home;

react: 16.4.2 
react-dom: 16.4.2 
react-redux: 5.0.7 
react-router-dom: 4.3.1 
react-router-redux: 5.0.0-alpha.9

感谢您抽出宝贵时间帮助我。

reactjs redux react-router-v4 react-router-dom
2个回答
0
投票

看着你的造型,它似乎是header has a negative z-index

通过设置负z-index,这可能会干扰<header>的孩子(即你的<nav>组件),从接收点击事件和/或正确响应光标。

我建议从你的z-index: -1;删除header.scss来解决你的问题。希望有所帮助!


1
投票

我将在这里做一个我通常使用的设置的简化示例。那么,这种方法呢?

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import Provider from "react-redux/es/components/Provider";
import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers/rootReducer';
import thunk from 'redux-thunk';

// Usually I would do this in an external file, but here I'm configuring my store

const myStore = configureStore(initialState) {
  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk)
  );
}    

// After that, I'm wrapping my App component inside of the Provider and passing in the configured store

ReactDOM.render((
    <Provider store={myStore }>
        <App/>
    </Provider>
), document.getElementById('root'));

App.js

import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom'
import PrimaryLayoutContainerComponent from "../containers/PrimaryLayoutContainer";

// In my App.js I'm wrapping my primary layout container with BrowserRouter to get access to the history and also passing in the props

class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <PrimaryLayoutContainerComponent {...this.props}/>
            </BrowserRouter>
        );
    }
}
export default App;

PrimaryLayoutContainerComponent.js 在这个(主容器)中,我将充分利用我之前的配置以及Redux状态管理所提供和需要的任何内容。我还在此阶段使用withRouter来访问历史对象的属性。

import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as myActions from '../actions';
import PrimaryLayout from "../components/layout/PrimaryLayout";
import { withRouter } from 'react-router';
import PropTypes from 'prop-types';


class PrimaryLayoutContainerComponent extends Component {
    render() {
        return (
            <div>
                 //Here we pass our history as props
                <PrimaryLayout  history={this.props.history} 
                                propsX={this.props.propsX}

                                propsY={this.props.actions.propsY}
                />
            </div>
        )
    }
}

// In these (and all other cases) I would highly recommend using propTypes.
// They could give you the answer in where the issues might be in your future development 

PrimaryLayoutContainerComponent.propTypes = {
    loggedUser: PropTypes.string,
    actions: PropTypes.object.isRequired
};

const mapStateToProps = (state) => {
    return { xxxx }
}

const mapDispatchToProps = (dispatch) => {
    return {
        actions: bindActionCreators(myActions, dispatch)
    };
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(PrimaryLayoutContainerComponent));

...然后最后在我的Primary Layout Component中,我将定义所有我的路线,如下所示:

PrimaryLayoutComponent.js

import React, { Component } from 'react';
import { Switch, Route, Redirect, Link } from 'react-router-dom';
// ... import all my compoenents


class PrimaryLayout extends Component {
    constructor(props) {
        super(props);
        this.state = {
            currentRoute: '' // I would use the state to dynamically change the  
                             // routes depending on which one was clicked
        }
    }



    componentWillReceiveProps(nextProps) {
        this.setState({
            currentRoute: nextProps.history.location.pathname
        })
    }

    componentWillMount() {
        this.setState({
            currentRoute: this.props.history.location.pathname
        })
    }

    render() {

        const { currentRoute } = this.state;

        return (
            <div className="wrapper">
                <header className="xxxx" role="banner">
                    <div className="container">
                        <div className="xxxxx">


                           <Link to="/home">
                             <img src={logo} alt="your logo"/> Your App Name
                           </Link>
                            <ul className="navbar__menu">
                                    <li className={currentRoute === "/home" ? "active" : ""}>
                                        <Link to="/home"> Home </Link>
                                    </li>

                                    <li className={currentRoute === "/componentOne" ? "active" : ""}>
                                        <Link to="/componentOne"> componentOne</Link>
                                    </li>

                                    <li className={currentRoute === "/componentTwo" ? "active" : ""}>
                                        <Link to="/componentTwo"> componentTwo</Link>
                                    </li>
                            </ul>

                        </div>
                    </div>
              </header>

// At the very end, I'm using the Switch HOC and defining my routes inside of a main tag

               <main>
                <Switch>
                      <Route path='/home' component={HomeContainerComponent} />
                  <Route path='/componentOne' component={componentOne} />               
                  <Route path='/componentTwo' component={componentTwo} />
                  <Redirect to="/home"/>
                </Switch>
                </main>
            </div>
        )
    }
}

export default PrimaryLayout;

我希望我的方法对您有所帮助,如果您有任何其他问题,请告诉我。我会尽快回答他们

© www.soinside.com 2019 - 2024. All rights reserved.