前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >component和render在react router中的应用

component和render在react router中的应用

作者头像
大神带我来搬砖
发布2019-04-17 17:28:42
1.8K0
发布2019-04-17 17:28:42
举报
文章被收录于专栏:大神带我来搬砖

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

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

component

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

代码语言:javascript
复制
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

列表页代码如下

代码语言:javascript
复制
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发生变化后重新获取数据。

代码语言:javascript
复制
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则可以减少三分之一的代码行数,此时详情页组件代码如下

代码语言:javascript
复制
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

列表页代码如下

代码语言:javascript
复制
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,可以避免组件复用,从而降低代码的复杂程度。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • component
  • render
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档