我正在尝试将以下代码片段转换为使用基于功能的组件。
class IssueTable extends React.Component {
constructor() {
super();
this.state = { issues: [] };
setTimeout(() => {
this.createIssue(sampleIssue);
}, 2000);
}
componentDidMount() {
this.loadData();
}
loadData() {
setTimeout(() => {
this.setState({ issues: initialIssues });
}, 500);
}
createIssue(issue) {
issue.id = this.state.issues.length + 1;
issue.created = new Date();
const newIssueList = this.state.issues.slice();
newIssueList.push(issue);
this.setState({ issues: newIssueList });
}
render() {
const issueRows = this.state.issues.map(issue =>
<IssueRow key={issue.id} issue={issue} />
);
return (
<table className="bordered-table">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Owner</th>
<th>Created</th>
<th>Effort</th>
<th>Due Date</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{issueRows}
</tbody>
</table>
);
}
}
在尝试将其转换为表格时,表格始终保持重新呈现状态,但我得到了关键的非唯一错误。我用过useEffect,但我不知道如何使用构造函数之类的功能。如何使用功能来实现它。 (issueRows是负责处理表中行数据的组件)。功能版本如下所示:
function IssueTable(){
const [issue1, setIssues] = React.useState([]);
React.useEffect(()=>{loadData()},[]);
setTimeout(() => {
createIssue(sampleIssue);
}, 2000);
function loadData() {
setTimeout(() => {
setIssues(issues);
}, 500);
}
function createIssue(issue) {
issue.id = issue1.length+1;
issue.created = new Date();
const newIssueList = issue1.slice();
newIssueList.push(issue);
setIssues(newIssueList);
}
const issueRows = issue1.map(issue =>
<IssueRow key={issue.id} issue={issue} />
)
return <table className="bordered-table">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Owner</th>
<th>Created</th>
<th>Effort</th>
<th>Due Date</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{issueRows}
</tbody>
</table>
}
function IssueRow(props){
return(
<tr>
<td>{props.issue.id}</td>
<td>{props.issue.status}</td>
<td>{props.issue.owner}</td>
<td>{props.issue.created.toDateString()}</td>
<td>{props.issue.effort}</td>
<td>{props.issue.due?props.issue.due.toDateString():""}</td>
<td>{props.issue.title}</td>
</tr>
);
}
答案 0 :(得分:1)
这应该在另一个private void checkVersion() {
Observable<String> observable = Observable.fromCallable(new Callable<String>() {
@Override
public String call() throws Exception {
String data = getHeadlines("https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "&hl=en");
return data;
}
});
}
public String getHeadlines(String source) throws IOException {
Document document = Jsoup.connect(source)
.timeout(30000)
.userAgent("Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
.referrer("http://www.google.com")
.get();
if (document != null) {
Elements element = document.getElementsContainingOwnText("Current Version");
for (Element ele : element) {
if (ele.siblingElements() != null) {
Elements sibElemets = ele.siblingElements();
for (Element sibElemet : sibElemets) {
newVersion = sibElemet.text();
}
}
}
}
return newVersion;
}
里面:
React.useEffect()
否则,它将循环运行每个渲染。根据经验,在useEffect之外不应有任何副作用。
答案 1 :(得分:1)
查看此工作沙箱: https://codesandbox.io/s/confident-taussig-tg3my?file=/src/App.js
要注意的一件事是,您不应该基于线性序列[或索引]建立键,因为这可能会使React的跟踪混乱。取而代之的是,将索引值从map传递到IssueRow组件以跟踪顺序,并为每个问题提供自己的序列化ID。
const issueRows = issues.map((issue, index) => (
<IssueRow key={issue.id} issue={issue} index={index} />
));
另外,更新依赖于先前状态的状态的正确方法是传递函数而不是对象:
setIssues(state => [...state, issue]);
您实质上是在迭代先前的状态,并添加新的问题。
答案 2 :(得分:0)
功能组件看起来像这样:
function IssueTable() {
const [issue1, setIssues] = React.useState([]);
const createIssue = React.useCallback(
function createIssue(issue) {
//passing callback to setIssues
// so useCallback does not depend
// on issue1 and does not have stale
// closure for issue1
setIssues((issues) => {
issue.id = issues.length + 1;
issue.created = new Date();
const newIssueList = issues.slice();
newIssueList.push(issue);
return newIssueList;
});
},
[]
);
React.useEffect(() => {
setTimeout(() => {
createIssue(sampleIssue);
}, 2000);
}, [createIssue]);
React.useEffect(() => {
setTimeout(() => {
setIssues(initialIssues);
}, 500);
}, []);
const issueRows = issue1.map((issue) => (
<IssueRow key={issue.id} issue={issue} />
));
return (
<table className="bordered-table">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Owner</th>
<th>Created</th>
<th>Effort</th>
<th>Due Date</th>
<th>Title</th>
</tr>
</thead>
<tbody>{issueRows}</tbody>
</table>
);
}