React 数组不随 setState 改变
React array not changing with setState
我的数组没有通过 setState
getter 添加新条目。
代码:
let calledOut = false;
export default function PayStation () {
const [records, setRecords] = useState([]);
// problem snippet
if (records.length === 0 && !calledOut) {
calledOut = true;
fetch('http://localhost:5000/api').then(
response => response.json()
).then(
data => {
const payloadRecords = data["records"];
// returning
// [{
// "attributes": {
// "type": "Contact",
// "url": "/services/data/v42.0/sobjects/Contact/0030U00001UPWYKQA5"
// },
// "Id": "0030U00001UPWYKQA5",
// "Name": "Contact25 Sequence Contact Manual Email"
// },
// {
// "attributes": {
// "type": "Contact",
// "url": "/services/data/v42.0/sobjects/Contact/0030U00001UPWYLQA5"
// },
// "Id": "0030U00001UPWYLQA5",
// "Name": "Contact26 Sequence Contact Manual Email"
// }
// ]
setRecords((records => [...records, ...payloadRecords]));
console.log("records size: " + records.length); // why is this still 0?
}
);
}
// end problem snippet
return (records.length === 0 ? "loading..." :
<div style={{
height: '100vh',
display: 'flex',
maxWidth: 600,
justifyContent: 'space-between',
alignItems: 'center'
}} >
{records}
</div>
);
}
我认为更改状态的要求是克隆状态变量(我相信我正在做),而不是为其分配引用并改变引用。
那么,为什么我的数组没有新条目?
组件的主体应该是一个纯函数。副作用(例如数据获取)应该包含在 useEffect 中。以下代码应该有效:
export default function PayStation () {
const [records, setRecords] = useState([]);
useEffect(() => {
const getRecords = () => {
fetch('http://localhost:5000/api').then(
response => response.json()
).then(
data => {
const payloadRecords = data["records"];
setRecords((records => [...records, ...payloadRecords]));
}
);
}
getRecords()
}, [])
if (records.length === 0) return "loading..."
return (
<div style={{
height: '100vh',
display: 'flex',
maxWidth: 600,
justifyContent: 'space-between',
alignItems: 'center'
}} >
{records.map((record) => <Record key={record.id} {...record} />)}
</div>
);
}
问题似乎是 useState 和 setState 都在同一个调用中 运行...而且由于它们都是异步的,所以 setState
没有设置任何值因为状态还没有被创建。如果您删除了 calledOut
变量,它应该可以正常工作。
这通常是一种糟糕的抓取方式。我建议做
useEffect(() => {
// fetch stuff here
}, []);
因此,这将在创建状态后调用。
我的数组没有通过 setState
getter 添加新条目。
代码:
let calledOut = false;
export default function PayStation () {
const [records, setRecords] = useState([]);
// problem snippet
if (records.length === 0 && !calledOut) {
calledOut = true;
fetch('http://localhost:5000/api').then(
response => response.json()
).then(
data => {
const payloadRecords = data["records"];
// returning
// [{
// "attributes": {
// "type": "Contact",
// "url": "/services/data/v42.0/sobjects/Contact/0030U00001UPWYKQA5"
// },
// "Id": "0030U00001UPWYKQA5",
// "Name": "Contact25 Sequence Contact Manual Email"
// },
// {
// "attributes": {
// "type": "Contact",
// "url": "/services/data/v42.0/sobjects/Contact/0030U00001UPWYLQA5"
// },
// "Id": "0030U00001UPWYLQA5",
// "Name": "Contact26 Sequence Contact Manual Email"
// }
// ]
setRecords((records => [...records, ...payloadRecords]));
console.log("records size: " + records.length); // why is this still 0?
}
);
}
// end problem snippet
return (records.length === 0 ? "loading..." :
<div style={{
height: '100vh',
display: 'flex',
maxWidth: 600,
justifyContent: 'space-between',
alignItems: 'center'
}} >
{records}
</div>
);
}
我认为更改状态的要求是克隆状态变量(我相信我正在做),而不是为其分配引用并改变引用。
那么,为什么我的数组没有新条目?
组件的主体应该是一个纯函数。副作用(例如数据获取)应该包含在 useEffect 中。以下代码应该有效:
export default function PayStation () {
const [records, setRecords] = useState([]);
useEffect(() => {
const getRecords = () => {
fetch('http://localhost:5000/api').then(
response => response.json()
).then(
data => {
const payloadRecords = data["records"];
setRecords((records => [...records, ...payloadRecords]));
}
);
}
getRecords()
}, [])
if (records.length === 0) return "loading..."
return (
<div style={{
height: '100vh',
display: 'flex',
maxWidth: 600,
justifyContent: 'space-between',
alignItems: 'center'
}} >
{records.map((record) => <Record key={record.id} {...record} />)}
</div>
);
}
问题似乎是 useState 和 setState 都在同一个调用中 运行...而且由于它们都是异步的,所以 setState
没有设置任何值因为状态还没有被创建。如果您删除了 calledOut
变量,它应该可以正常工作。
这通常是一种糟糕的抓取方式。我建议做
useEffect(() => {
// fetch stuff here
}, []);
因此,这将在创建状态后调用。