Skip to main content
 首页 » 编程设计

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

2025年01月19日10pander-it

我有一个简单的应用程序,带有主屏幕、博客主列表和博客详细信息页面。从主屏幕导航到博客列表并按预期返回。当我单击其中一篇博文时,应用程序会导航到该页面并呈现该博文。但是当我回到博客主列表时,博客文章现在位于博客列表的最底部。如果我随后以同样的方式导航回主页,则博客文章位于主页图形后面的 DOM 中。

我正在使用 React 路由器 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> 

请您参考如下方法:

我不确定为什么它会继续渲染整个组件,但如果我去掉 <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> 
 
        )