2017-09-19 2 views
1

Ich arbeite an der Erstellung einer einfachen Hacker News App mit React und Redux und ich habe Probleme mit dem Rendern einer einzelnen Artikelseite Komponente (die ArticleSingle-Komponenten).React Router - Pfad Komponente ist nicht Rendering

Das Routing funktioniert einwandfrei, aber die ArticleSingle-Komponente wird beim Klicken nicht gerendert.

Hier ist meine Root-Datei, die alle von der Routing-Griffe:

// 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; 

Hier ist die ArticleSingle Komponente, die der ist, das ich habe Probleme mit. Letztendlich möchte ich erreichen, dass die ID von der URL an eine von AppContainer übergebene Aktion übergeben wird, aber ich hatte gehofft, dass die Komponente etwas auf der Seite (die ID) rendert, bevor die Redux-Arbeit gestartet wird.

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

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

Hier ist die Hauptkomponente, es verfügt über eine Filterleiste, was, warum gibt es zwei Wege für sie

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; 

Hier ist der AppContainer, steuert den Zustand für alle der App.

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); 
+0

Wenn Sie/article/someid besuchen, erhalten Sie irgendwelche Konsolenfehler? Wenn ja, bitte zeigen Sie sie hier. Wenn Sie die gleiche URL besuchen, was sehen Sie dann im Browser? –

+0

Ich bekomme keine Konsolenfehler, die Seite bleibt auf der Home-Komponente, anstatt den ArticleSingle zu rendern. Die URL wird beim Klicken korrekt aktualisiert. – user6456392

Antwort

1

Ich sehe ein paar Probleme in Ihrem Code.

1) Hier können Sie <Route path="/articles/:article_id" component={ArticleSingle} /> haben sagen - Um die article_id in ArticleSingle Componenet zugreifen Sie props.match.params.article_id

2) Dies ist Ihre Route verwenden müssen:

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

Grundsätzlich, wenn Sie besuchen/Artikel/Artikel -Ist du die erste Route <Route path="/" component={AppContainer} /> übereinstimmen und Sie sind dabei. Um dieses Problem zu beheben, können Sie einen der folgenden Schritte ausführen:

A. Verwenden Sie in Ihren ersten beiden Routen exact. Das wäre <Route exact path="/" component={AppContainer} /> und <Route exact path="/" component={Home} />

B. Ändern Sie die Reihenfolge der Strecken sein und doch die Homepage Wurzel am Boden wie folgt aus:

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

Für die oben genannten Lösungen, gehe ich davon aus das Sie verwenden Router React 4. Ich habe die Informationen erhalten, die ich Ihnen von diesem Tutorial gegeben habe: https://medium.com/@pshrmn/a-simple-react-router-v4-tutorial-7f23ff27adf

+0

Vielen Dank, das hat es gelöst! Ich überprüfe auch das Tutorial! – user6456392

+0

Dieses Tutorial ist ziemlich umfangreich. Sie sollten alles finden, was Sie auf Reagieren Router 4 brauchen :) –

Verwandte Themen