好了,我希望你花时间自己试着完成了这个任务,因为他真的对巩固知识很有用。没做出来也没关系,我答应给你写完的,下面放出代码:
首先要做的是更新组件的初始状态,以便保存三种数据: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;
正如你所看到的,没什么特别有趣的地方,只是把我们已经写过的东西重复三遍。