美文网首页技术干货程序员
component和render在react router中的应

component和render在react router中的应

作者: 大神带我来搬砖 | 来源:发表于2019-04-04 16:33 被阅读0次

    在react router项目中,有这样的一个需求,首先展示用户名列表,点击某个用户名后,根据用户名在后台取得用户具体信息在详情页进行展示。

    此时可以将详情页封装成一个组件,利用react router将userId传递给详情页组件,详情页组件向后台请求数据,然后进行展示。

    component

    使用component时,详情页组件代码如下

    import {PureComponent, Component} from "react";
    import React from "react";
    
    class ComponentUser extends PureComponent {
    
        constructor(props) {
            super(props);
            this.state = {}
        }
    
        getUserId = () => {
            const {
                match: {
                    params: {id},
                },
            } = this.props;
            return id;
        };
    
        fetchContent = (userId) => {
            console.log("fetch");
            this.setState({content: "loading"});
            new Promise(resolve => {
                setTimeout(() => {
                    resolve("content of " + userId)
                }, 2000)
            }).then(content => {
                this.setState({content})
            })
        };
    
        componentDidMount() {
            const userId = this.getUserId();
            this.fetchContent(userId);
        }
    
        render() {
            const userId = this.getUserId();
            const {content} = this.state;
    
            return (
                <div>
                    <div>{userId}</div>
                    <div>{content}</div>
                </div>
    
            )
        }
    }
    
    export default ComponentUser
    

    列表页代码如下

    import React from "react";
    import {BrowserRouter as Router, Route, Link} from "react-router-dom";
    import RenderUser from './RenderUser'
    import ComponentUser from './ComponentUser'
    
    const App = () => (
        <Router>
            <div>
                <nav>
                    <ul>
                        <li>
                            <Link to="/componentUser/user1">userA</Link>
                        </li>
                        <li>
                            <Link to="/componentUser/user2">userB</Link>
                        </li>
                    </ul>
                </nav>
    
                <Route path="/componentUser/:id" component={ComponentUser}/>
            </div>
        </Router>
    );
    
    export default App;
    

    不过此时会有个问题,切换点击切换userA和userB的时候,发现页面并没有更新,这是由component属性的性质决定的,react会进行组件复用。

    所以需要在组件中添加componentDidUpdate函数,期望在userId发生变化后重新获取数据。

    import {PureComponent, Component} from "react";
    import React from "react";
    
    class ComponentUser extends PureComponent {
    
        constructor(props) {
            super(props);
            this.state = {}
        }
    
        getUserId = () => {
            const {
                match: {
                    params: {id},
                },
            } = this.props;
            return id;
        };
    
        fetchContent = (userId) => {
            console.log("fetch");
            this.setState({content: "loading"});
            new Promise(resolve => {
                setTimeout(() => {
                    resolve("content of " + userId)
                }, 2000)
            }).then(content => {
                this.setState({content})
            })
        };
    
        componentDidMount() {
            const userId = this.getUserId();
            this.fetchContent(userId);
        }
    
        componentDidUpdate(prevProps) {
            const userId = this.getUserId();
            const {
                match: {
                    params: {id: previousUserId},
                },
            } = prevProps;
            if (userId !== previousUserId) {
                this.fetchContent(userId);
            }
        }
    
        render() {
            const userId = this.getUserId();
            const {content} = this.state;
    
            return (
                <div>
                    <div>{userId}</div>
                    <div>{content}</div>
                </div>
    
            )
        }
    }
    
    export default ComponentUser
    

    这里要注意的是,componentDidUpdate中需要判断当前的userId是否和原来的userId一致,只有不一致的时候才需要重新获取数据。不这样做的话,会导致无限循环的setState和componentDidUpdate。

    render

    使用render则可以减少三分之一的代码行数,此时详情页组件代码如下

    import {PureComponent} from "react";
    import React from "react";
    
    class RenderUser extends PureComponent {
    
        constructor() {
            super();
            this.state = {}
        }
    
        componentDidMount() {
            console.log("fetch");
            this.setState({content: "loading"});
            const {userId} = this.props;
            new Promise(resolve => {
                setTimeout(() => {
                    resolve("content of " + userId)
                }, 1000)
            }).then(content => {
                this.setState({content})
            })
        }
    
    
        render() {
            const {userId} = this.props;
            const {content} = this.state;
    
            return (
                <div>
                    <div>{userId}</div>
                    <div>{content}</div>
                </div>
    
            )
        }
    }
    
    export default RenderUser
    

    列表页代码如下

    import React from "react";
    import {BrowserRouter as Router, Route, Link} from "react-router-dom";
    import RenderUser from './RenderUser'
    import ComponentUser from './ComponentUser'
    
    const App = () => (
        <Router>
            <div>
                <nav>
                    <ul>
                        <li>
                            <Link to="/renderUser/user1">user1</Link>
                        </li>
                        <li>
                            <Link to="/renderUser/user2">user2</Link>
                        </li>
                    </ul>
                </nav>
    
                <Route path="/renderUser/:id" render={
                    ({match}) => (<RenderUser key={match.params.id} userId={match.params.id}/>)
                }/>
            </div>
        </Router>
    );
    
    export default App;
    

    可以看到由于将userId作为组件的key,可以避免组件复用,从而降低代码的复杂程度。

    相关文章

      网友评论

        本文标题:component和render在react router中的应

        本文链接:https://www.haomeiwen.com/subject/uccqiqtx.html