Javascript 将基于类的组件转换为功能组件
我试图将下面的代码片段转换为使用基于函数的组件Javascript 将基于类的组件转换为功能组件,javascript,reactjs,react-functional-component,Javascript,Reactjs,React Functional Component,我试图将下面的代码片段转换为使用基于函数的组件 class IssueTable extends React.Component { constructor() { super(); this.state = { issues: [] }; setTimeout(() => { this.createIssue(sampleIssue); }, 2000); } componentDidMount() { this.load
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>
);
}
}
class IssueTable扩展了React.Component{
构造函数(){
超级();
this.state={issues:[]};
设置超时(()=>{
this.createIssue(sampleIssue);
}, 2000);
}
componentDidMount(){
这是loadData();
}
loadData(){
设置超时(()=>{
this.setState({issues:initialIssues});
}, 500);
}
创建问题(问题){
issue.id=this.state.issues.length+1;
issue.created=新日期();
const newIssueList=this.state.issues.slice();
newIssueList.push(发布);
this.setState({issues:newIssueList});
}
render(){
const issueRows=this.state.issues.map(issue=>
);
返回(
身份证件
地位
所有者
创建
努力
到期日
标题
{issueRows}
);
}
}
当试图转换它时,表不知何故一直在重新排序,我得到的键不是唯一的错误。我使用了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>
);
}
函数IssueTable(){
const[issue1,setIssues]=React.useState([]);
React.useffect(()=>{loadData()},[]);
设置超时(()=>{
createIssue(sampleIssue);
}, 2000);
函数loadData(){
设置超时(()=>{
设置问题(问题);
}, 500);
}
函数createIssue(问题){
issue.id=issue1.length+1;
issue.created=新日期();
const newIssueList=issue1.slice();
newIssueList.push(发布);
setIssues(newIssueList);
}
const issueRows=issue1.map(issue=>
)
返回
身份证件
地位
所有者
创建
努力
到期日
标题
{issueRows}
}
功能发布程序(道具){
返回(
{props.issue.id}
{props.issue.status}
{props.issue.owner}
{props.issue.created.toDateString()}
{props.issue.efforce}
{props.issue.due?props.issue.due.toDateString():“”
{props.issue.title}
);
}
这应该在另一个React.useffect()中。
:
否则,它将在循环中运行每个渲染。一般来说,除了useEffect之外,不应有任何副作用。请查看此工作沙盒: 需要注意的一件事是,您不应该基于线性序列(或索引)的关键点,因为这可能会打乱React的跟踪。相反,将索引值从map传递到IssueRow组件以跟踪顺序,并为每个问题提供自己的序列化id
const issueRows = issues.map((issue, index) => (
<IssueRow key={issue.id} issue={issue} index={index} />
));
您基本上迭代了以前的状态,并添加了新问题。功能组件可以如下所示:
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>
);
}
函数IssueTable(){
const[issue1,setIssues]=React.useState([]);
const createIssue=React.useCallback(
函数createIssue(问题){
//将回调传递给setIssues
//所以useCallback不依赖于
//在问题1上,并且没有过时的
//问题1的关闭
设置问题((问题)=>{
issue.id=issues.length+1;
issue.created=新日期();
const newIssueList=issues.slice();
newIssueList.push(发布);
返回newIssueList;
});
},
[]
);
React.useffect(()=>{
设置超时(()=>{
createIssue(sampleIssue);
}, 2000);
},[createIssue]);
React.useffect(()=>{
设置超时(()=>{
设置问题(初始问题);
}, 500);
}, []);
const issueRows=issue1.map((问题)=>(
));
返回(
身份证件
地位
所有者
创建
努力
到期日
标题
{issueRows}
);
}
将功能版本放在此处,说明什么是示例问题
和问题
?它们从未在您的功能组件中定义。感谢您的回答!!我将setTimeout包装到一个函数中,然后在useEffect中调用它。它可以正常工作,没有任何错误,但问题是它不知何故失去了对数组issue1中先前数据的访问,只渲染了一行。请您调查一下,告诉我如何获取当前值,而不是使用陈旧数据。我不熟悉异步js,不知道如何处理它
setIssues(state => [...state, issue]);
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>
);
}