React Router - 路径组件未呈现

时间:2017-09-19 08:41:14

标签: reactjs redux react-router

我正在使用React和Redux构建一个简单的黑客新闻应用程序,而我在渲染单个文章页面组件(ArticleSingle组件)时遇到了问题。

路由工作正常,但ArticleSingle组件不会在点击时呈现。

这是我的Root文件,它处理所有路由:

// REACT
import React from 'react';
import PropTypes from 'prop-types';

// REACT ROUTER
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

// REDUX
import { Provider } from 'react-redux';
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();

// COMPONENTS
import AppContainer from './components/containers/AppContainer';
import Home from './components/presentational/Home';
import ArticleSingle from './components/presentational/ArticleSingle';

const Root = ({ store }) => (
  <Provider store={store}>
    <Router history={history}>
      <Switch>
        <Route path="/" component={AppContainer} />
        <Route path="/" component={Home} />
        <Route path="/topics/:topic_name/articles" component={Home} />
        <Route path="/articles/:article_id" component={ArticleSingle} />
      </Switch>
    </Router>
  </Provider>
);

Root.propTypes = {
  store: PropTypes.object.isRequired
};

export default Root;

这是ArticleSingle组件,这是我遇到麻烦的组件。我最终希望将它从URL传递给从AppContainer传递下来的动作,但我希望在开始redux工作之前让组件在页面上呈现一些内容(id)。

import React from 'react';
import PropTypes from 'prop-types';

const ArticleSingle = ({ params, children }) => (
  <div>
    {params.article_id}
    {children}
  </div>
);
export default ArticleSingle;

这是Home组件,它有一个过滤条,为什么有两条路径

import React from 'react';
import PropTypes from 'prop-types';

// Components
import Spinner from 'react-spinkit';
import ArticleList from './ArticleList';
import TopicsSubNav from './TopicsSubNav';

const Home = ({
  loading,
  articles,
  topics,
  fetchTopicArticles,
  fetchArticles,
  children
}) => {
  return (
    <div>
      <h3 className="title is-3">Northcoders News</h3>
      <div id="TopicsSubNav">
        {loading && <Spinner name="pacman" color="coral" fadeIn="none" />}
        <TopicsSubNav
          topics={topics}
          onTopicClick={fetchTopicArticles}
          onAllClick={fetchArticles}
        />
      </div>
      {loading && <Spinner name="pacman" color="coral" fadeIn="none" />}
      <ArticleList articles={articles} topics={topics} />
      { children }
    </div>
  );
};

Home.propTypes = {
  articles: PropTypes.array.isRequired,
  topics: PropTypes.array.isRequired,
  loading: PropTypes.bool,
  fetchTopicArticles: PropTypes.func.isRequired,
  fetchArticles: PropTypes.func.isRequired
};

export default Home;

这是AppContainer,控制所有应用程序的状态。

import React from 'react';
import PropTypes from 'prop-types';
import Home from '../presentational/Home';
import ArticleSingle from '../presentational/ArticleSingle';

// Redux
import { connect } from 'react-redux';
import * as actions from '../../actions/actions';

class AppContainer extends React.Component {
  componentDidMount () {
    this.props.fetchArticles();
    this.props.fetchTopics();
  }

  render () {
    return (
      <div>
        <Home
          articles={this.props.articles}
          topics={this.props.topics}
          loading={this.props.loading}
          fetchTopicArticles={this.props.fetchTopicArticles}
          fetchArticles={this.props.fetchArticles}
        />
      </div>
    );
  }
}

function mapDispatchToProps (dispatch) {
  return {
    fetchArticles: () => {
      dispatch(actions.fetchArticles());
    },
    fetchTopics: () => {
      dispatch(actions.fetchTopics());
    },
    fetchTopicArticles: topic => {
      dispatch(actions.fetchTopicArticles(topic));
    },
    fetchArticleById: id => {
      dispatch(actions.fetchArticleById(id));
    }
  };
}

function mapStateToProps (state) {
  return {
    articles: state.articles.data,
    article: state.article,
    topics: state.topics.data,
    loading: state.loading
  };
}

AppContainer.propTypes = {
  articles: PropTypes.array.isRequired,
  topics: PropTypes.array.isRequired,
  loading: PropTypes.bool,
  fetchArticles: PropTypes.func.isRequired,
  fetchTopics: PropTypes.func.isRequired,
  fetchTopicArticles: PropTypes.func.isRequired,
  fetchArticleById: PropTypes.func.isRequired
};

export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);

1 个答案:

答案 0 :(得分:2)

我在您的代码中看到了一些问题。

1)假设您有<Route path="/articles/:article_id" component={ArticleSingle} /> - 要访问ArticleSingle Componenet中的article_id,您需要使用props.match.params.article_id

2)这是你的路线:

<Route path="/" component={AppContainer} />
<Route path="/" component={Home} />
<Route path="/topics/:topic_name/articles" component={Home} />
<Route path="/articles/:article_id" component={ArticleSingle} />

基本上,当您访问/ articles / article-id时,您正在匹配第一条路线<Route path="/" component={AppContainer} />并且您正在进入它。 要解决此问题,您可以执行以下操作之一:

一个。在前两条路线中使用exact。那将是<Route exact path="/" component={AppContainer} /><Route exact path="/" component={Home} />

B中。更改路线的顺序,但底部的主页根目录如下:

<Route path="/topics/:topic_name/articles" component={Home} />
<Route path="/articles/:article_id" component={ArticleSingle} />
<Route path="/" component={AppContainer} />
<Route path="/" component={Home} />

对于上述解决方案,我假设您使用的是React Router 4.我从本教程中获得了我提供的信息: https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf