导航到另一个页面后,为什么我的React组件仍保留在DOM中?

时间:2017-06-21 23:40:56

标签: javascript reactjs react-router

我有一个简单的应用程序,主屏幕,博客主列表,然后博客详细信息页面。从主屏幕导航到博客列表并返回按预期工作。当我点击其中一篇博文时,该应用会导航到该页面并呈现博客帖子。但是当我回到博客主列表时,博客文章现在位于博客列表的最底层。如果我然后导航回主页同样的事情,博客文章在主页图形后面的DOM中。

我正在使用react router 4.1。

是否与我的路线设置有关?

import React, { Component } from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import NavBar from './components/NavBar'
import Blog from './pages/blog'
import Home from './pages/home'
import Post from './pages/post'
import './css/App.css'

class App extends Component {
  render() {
    return (
      <Router>
          <div className="App">
            <NavBar />
            <Route exact path='/' component={Home} />
            <Route path='/blog' component={Blog} />
            <Route path='/post/:slug' component={Post} />
          </div>
      </Router>
    )
  }
}

export default App

或者使用我的帖子组件

import React from 'react'
import fetch from 'isomorphic-unfetch'
import NavBar from '../components/NavBar'
import dateUtils from '../utilities/DateAndTime'

const classNames = require('classnames')


class Post extends React.Component {

    constructor(props) {
        super(props)

        this.state = {
            blogObject: null,
            fetchBlogObject: false
        }

        this.fetchBlogObject = this.fetchBlogObject.bind(this)
        this.createMarkup = this.createMarkup.bind(this)
        this.assignStyleToCoverImage = this.assignStyleToCoverImage.bind(this)
        this.formatDateString = this.formatDateString.bind(this)

    }

    componentWillMount() {
        this.fetchBlogObject()
    }


    componentWillReceiveProps() {
        this.fetchBlogObject()
    }

    fetchBlogObject() {

            console.log('fetching')

            this.setState({ fetchBlogObject: true })

            fetch(`*******************`)
            .then(response => response.json())
            .then((responseJson) => {
                console.log(responseJson)
                this.setState({ blogObject: responseJson.object })
            })


    }


    createMarkup(stringToConvertToHtml) {
        return { __html: stringToConvertToHtml }
    }


    assignStyleToCoverImage() {

        const style = {
            background: `url(${this.state.blogObject.metadata.hero.url})`,
            height: '35vh',
            backgroundSize: 'cover',
            backgroundPosition: 'center'
        }

        return style

    }


    formatDateString(dateString) {
        console.log(dateString)

        const d = `${dateUtils.returnMonthFromISODateString(dateString)} ${dateUtils.returnDateNumberFromISOString(dateString)}, ${dateUtils.returnFullYearFromISOString(dateString)} by Phil Andrews`
        return d
    }

    render() {


        const postContainerClasses = classNames({
            'post-container': true
        })

        const postBodyClasses = classNames({
            'post-body': true
        })

        return (

            <div>
                <NavBar />

                {this.state.blogObject ?

                    <div className={postContainerClasses} >
                        <div className='header-image' style={this.assignStyleToCoverImage(this.state.blogObject)} />
                        <div className='post-body-padding'>
                            <div className='post-header-info'>
                                <h1 className='post-title'>{this.state.blogObject.title}</h1>
                                <h4 className='post-date'>{this.formatDateString(this.state.blogObject.created_at)}</h4>
                            </div>
                            <div className={postBodyClasses} dangerouslySetInnerHTML={this.createMarkup(this.state.blogObject.content)} />
                        </div>
                    </div>

                : <div>Loading...</div>

                }

            </div>

        )

    }
}

export default Post

或者使用博客列表按钮操作导航到帖子页面?

<Link id={this.props.blogObject.slug} to={`/post/${this.props.blogObject.slug}`}>
    <button className='blog-button' style={buttonStyle} id={this.props.blogObject.slug} />
</Link>

1 个答案:

答案 0 :(得分:0)

我不确定为什么会继续渲染整个组件,但如果我摆脱<NavBar />组件中的post,问题就会消失。

无效

 return (

            <div>
                <NavBar />

                {this.state.blogObject ?

                    <div className={postContainerClasses} >
                        <div className='header-image' style={this.assignStyleToCoverImage(this.state.blogObject)} />
                        <div className='post-body-padding'>
                            <div className='post-header-info'>
                                <h1 className='post-title'>{this.state.blogObject.title}</h1>
                                <h4 className='post-date'>{this.formatDateString(this.state.blogObject.created_at)}</h4>
                            </div>
                            <div className={postBodyClasses} dangerouslySetInnerHTML={this.createMarkup(this.state.blogObject.content)} />
                        </div>
                    </div>

                : <div>Loading...</div>

                }

            </div>

        )

<强>工作

 return (

            <div>

                {this.state.blogObject ?

                    <div className={postContainerClasses} >
                        <div className='header-image' style={this.assignStyleToCoverImage(this.state.blogObject)} />
                        <div className='post-body-padding'>
                            <div className='post-header-info'>
                                <h1 className='post-title'>{this.state.blogObject.title}</h1>
                                <h4 className='post-date'>{this.formatDateString(this.state.blogObject.created_at)}</h4>
                            </div>
                            <div className={postBodyClasses} dangerouslySetInnerHTML={this.createMarkup(this.state.blogObject.content)} />
                        </div>
                    </div>

                : <div>Loading...</div>

                }

            </div>

        )