简单易懂的React魔法

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

2017-08-18  本文已影响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;

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

上一篇下一篇

猜你喜欢

热点阅读