美文网首页简单易懂的React魔法
简单易懂的React魔法(18):如何修改应用来处理三种数据

简单易懂的React魔法(18):如何修改应用来处理三种数据

作者: 誅诺 | 来源:发表于2017-08-18 19:01 被阅读13次

    好了,我希望你花时间自己试着完成了这个任务,因为他真的对巩固知识很有用。没做出来也没关系,我答应给你写完的,下面放出代码:

    首先要做的是更新组件的初始状态,以便保存三种数据:commit,fork,pulls。 它还需要一个值来区分现在显示的是什么数据。 代码如下:
    src/pages/Detail.js

    this.state = {
        mode: 'commits',
        commits: [],
        forks: [],
        pulls: []
    };
    

    第二件事是更新componentWillMount(),以便它调用三次API。 我们只是复制代码三次。 不要担心,我们会很快改进这里。
    这是新的 componentWillMount() 的方法:

    src/pages/Detail.js

    componentWillMount() {
        ajax.get('https://api.github.com/repos/facebook/react/commits')
            .end((error, response) => {
                if (!error && response) {
                    this.setState({ commits: response.body });
                } else {
                    console.log('Error fetching commits', error);
                }
            }
        );
    
        ajax.get('https://api.github.com/repos/facebook/react/forks')
            .end((error, response) => {
                if (!error && response) {
                    this.setState({ forks: response.body });
                } else {
                    console.log('Error fetching forks', error);
                }
            }
        );
    
        ajax.get('https://api.github.com/repos/facebook/react/pulls')
            .end((error, response) => {
                if (!error && response) {
                    this.setState({ pulls: response.body });
                } else {
                    console.log('Error fetching pulls', error);
                }
            }
        );
    }
    

    接下来,我们需要三种render方法,以便显示相关信息。我命名他们为renderCommits(),renderForks()和renderPulls():

    src/pages/Detail.js

    renderCommits() {
        return this.state.commits.map((commit, index) => {
            const author = commit.author ? commit.author.login : 'Anonymous';
    
            return (<p key={index}>
                <strong>{author}</strong>:
                <a href={commit.html_url}>{commit.commit.message}</a>.
            </p>);
        });
    }
    
    renderForks() {
        return this.state.forks.map((fork, index) => {
            const owner = fork.owner ? fork.owner.login : 'Anonymous';
    
            return (<p key={index}>
                <strong>{owner}</strong>: forked to
                <a href={fork.html_url}>{fork.html_url}</a> at {fork.created_at}.
            </p>);
        });
    }
    
    renderPulls() {
        return this.state.pulls.map((pull, index) => {
            const user = pull.user ? pull.user.login : 'Anonymous';
    
            return (<p key={index}>
                <strong>{user}</strong>:
                <a href={pull.html_url}>{pull.body}</a>.
            </p>);
        });
    }
    

    注意:你可能需要调整renderForks()方法,以便链接和“fork to”在同一行上,不然的话React不会在单词之间留下任何空格。

    这样就可以使用自己的方法隔离每次渲染,这意味着我们现在只需要使render()选择显示哪一个。 我使用state中的mode值来决定要显示哪个,它有三个值:‘commits,“forks“和“pulls’。

    考虑到这一点,下面给出render();
    src/pages/Detail.js

    render() {
        let content;
    
        if (this.state.mode === 'commits') {
            content = this.renderCommits();
        } else if (this.state.mode === 'forks') {
            content = this.renderForks();
        } else {
            content = this.renderPulls();
        }
    
        return (<div>
            <button onClick={this.showCommits.bind(this)}>Show Commits</button>
            <button onClick={this.showForks.bind(this)}>Show Forks</button>
            <button onClick={this.showPulls.bind(this)}>Show Pulls</button>
            {content}
        </div>);
    }
    

    你可以在方法的末尾看到三个按钮,当它们被单击时调用三个还没定义的方法:showCommits(),showForks()和showPulls()。 这些方法的功能是更改模式状态:

    src/pages/Detail.js

    showCommits() {
        this.setState({ mode: 'commits' });
    }
    
    showForks() {
        this.setState({ mode: 'forks' });
    }
    
    showPulls() {
        this.setState({ mode: 'pulls' });
    }
    

    记住,更改组件state或props会自动重新渲染组件,也就是说通过点击就可以得到我们想要的效果。
    在我们继续之前,给出完整的Detail.js,你可以看看和我的相比你少了什么东西:

    src/pages/Detail.js

    import React from 'react';
    import ajax from 'superagent';
    
    class Detail extends React.Component {
        constructor(props) {
            super(props);
    
            this.state = {
                mode: 'commits',
                commits: [],
                forks: [],
                pulls: []
            };
        }
    
        componentWillMount() {
            ajax.get('https://api.github.com/repos/facebook/react/commits')
                .end((error, response) => {
                    if (!error && response) {
                        this.setState({ commits: response.body });
                    } else {
                        console.log('Error fetching commits', error);
                    }
                }
            );
    
            ajax.get('https://api.github.com/repos/facebook/react/forks')
                .end((error, response) => {
                    if (!error && response) {
                        this.setState({ forks: response.body });
                    } else {
                        console.log('Error fetching forks', error);
                    }
                }
            );
    
            ajax.get('https://api.github.com/repos/facebook/react/pulls')
                .end((error, response) => {
                    if (!error && response) {
                        this.setState({ pulls: response.body });
                    } else {
                        console.log('Error fetching pulls', error);
                    }
                }
            );
        }
    
        showCommits() {
            this.setState({ mode: 'commits' });
        }
    
        showForks() {
            this.setState({ mode: 'forks' });
        }
    
        showPulls() {
            this.setState({ mode: 'pulls' });
        }
    
        renderCommits() {
            return this.state.commits.map((commit, index) => {
                const author = commit.author ? commit.author.login : 'Anonymous';
    
                return (<p key={index}>
                    <strong>{author}</strong>:
                    <a href={commit.html_url}>{commit.commit.message}</a>.
                </p>);
            });
        }
    
        renderForks() {
            return this.state.forks.map((fork, index) => {
                const owner = fork.owner ? fork.owner.login : 'Anonymous';
    
                return (<p key={index}>
                    <strong>{owner}</strong>: forked to
                    <a href={fork.html_url}>{fork.html_url}</a> at {fork.created_at}.
                </p>);
            });
        }
    
        renderPulls() {
            return this.state.pulls.map((pull, index) => {
                const user = pull.user ? pull.user.login : 'Anonymous';
    
                return (<p key={index}>
                    <strong>{user}</strong>:
                    <a href={pull.html_url}>{pull.body}</a>.
                </p>);
            });
        }
    
        render() {
            let content;
    
            if (this.state.mode === 'commits') {
                content = this.renderCommits();
            } else if (this.state.mode === 'forks') {
                content = this.renderForks();
            } else {
                content = this.renderPulls();
            }
    
            return (<div>
                <button onClick={this.showCommits.bind(this)}>Show Commits</button>
                <button onClick={this.showForks.bind(this)}>Show Forks</button>
                <button onClick={this.showPulls.bind(this)}>Show Pulls</button>
                {content}
            </div>);
        }
    }
    
    export default Detail;
    

    正如你所看到的,没什么特别有趣的地方,只是把我们已经写过的东西重复三遍。

    相关文章

      网友评论

        本文标题:简单易懂的React魔法(18):如何修改应用来处理三种数据

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