仅在网址更改后,React Router会渲染一次组件

时间:2020-08-10 16:06:30

标签: javascript reactjs react-router

我的页面上有一个导航栏和一个侧栏。

导航栏由家庭和博客组成

博客将呈现BlogHome组件,该组件将从db获取链接,单击任何链接将呈现BlogContent组件。

可以说侧边栏列出了Blog1,Blog2和Blog3。如果我单击Blog1,它将正确显示Blog1的内容,但是如果再次单击Blog2,它将仅更改URL,而不更改Blog2的内容。

请看一下我的代码:

Navbar.js

      <Router>
            <Container className="p-0" fluid={true}>
                <Navbar className="border-bottom" bg="transparent" expand="lg">
                    <Navbar.Brand>{global.config.appname}</Navbar.Brand>
                    <Navbar.Toggle className="border-0" aria-controls="navbar-toggle" />
                    <Navbar.Collapse id="navbar-toggle">
                        <Nav className="ml-auto">
                            <Link className="nav-link" to="/">Home</Link>
                            <Link className="nav-link" to="/blogs/main">Blogs</Link>
                            <Link className="nav-link" to="/contact">Contact</Link>
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>
                </Container>
                <Switch>
                    <Route exact path="/" component={Home}></Route>
                    <Route exact path="/blogs/main" component={BlogHome}></Route>
                </Switch>
            </Router>

BlogHome.js


export default class BlogHome extends Component {
    constructor(props)
    {
        super(props);
        this.state = { data: null,route:null };
    }
    componentDidMount = () => {
        console.log("BlogHome");
        BlogDataService.getAll().then(data => {
            let data_temp = []
            let cnt = 0;
            for (let item of data.data) {

                data_temp.push(
                <MenuItem key={cnt++} icon={<FaBlog />}>
                    <Link to={"/blogs/main/" + item.id}>{item.title}</Link>
                </MenuItem>
                );
                
            }
            this.setState({ data: data_temp });
        })
    }
    render() {
        return (
            <Router>
                <div style={{ display: "flex" }}>
                <ProSidebar>
                    <Menu iconShape="square">
                        {this.state.data}
                    </Menu>
                </ProSidebar>
                    
                <Switch>
                    <Route exact path={"/blogs/main/:blogId"} component={BlogContent}></Route>
                </Switch>
                </div>
            </Router>
        );
    }
}

BlogContent.js


export default class BlogContent extends Component {
    constructor(props) {
        super(props);
        const contentState = convertFromRaw(content);
        this.state = {
            contentState,
            item_id: this.props.match.params.blogId,
            title:null
        }
        console.log(this.props.match);
    }

    onContentStateChange: function = (contentState) => {
        this.setState({
            contentState,
        });
    };
    componentDidMount = () => {
        BlogDataService.get(this.state.item_id).then(data => {
            console.log(data);
            this.setState({ title: data.data.title })
        });
    }
    render() {
        const { contentState } = this.state;
        return (
            <Router>
            <div style={{padding:"10px"}}>
                <div style={{padding:"50px",fontSize:"50px"}}>
                    {this.state.title}
                </div>
            <Editor
                wrapperClassName="demo-wrapper"
                editorClassName="demo-editor"
                onContentStateChange={this.onContentStateChange}
                    />
            <Route exact path={"/blogs/main/1"} component={BlogContent}></Route>
                </div>
            </Router>
        );
    }
}

感谢您阅读:)

1 个答案:

答案 0 :(得分:1)

您的item_id仅设置了一次,并且完全没有改变。第一次加载组件时,它将起作用,但是当您第二次传递时,您传递的是新的项目ID,但是组件不知道此更改,因此无能为力。

尝试创建一个获取数据的函数。相同的函数在componentDidmount中调用它。 现在,当它有新的道具时,该检查一下了。使用componentDidUpdate。

componentDidUpdate(prevProps, prevState){ 
   if(prevProps.blogId != this.props.blogId){
        this.setState({
           item_id: this.props.blogId 
       }, () => { call the function to get the data } )
  }
}