react 中的 useState() 不更新数据——这是 sort() 的问题吗?
useState() in react does not update the data - is this the sort() issue?
当我点击按钮对网站加载后的国家数据进行排序时,数据显示正确。但是当我想按不同的值再次对其进行排序时,数据不会更新,状态也不会更新,但是,该函数运行良好,因为我可以看到控制台中的结果已正确排序。这种奇怪行为的原因可能是什么?谢谢你的时间。
function AllCountries({ countries }) {
const [sortedCountries, setSortedCountries] = useState([]);
useEffect(() => {
console.log(sortedCountries)
}, [sortedCountries])
const sortResults = (val) => {
let sortedResults = countries.sort((a, b) => {
if (val === "deaths") {
return b.TotalDeaths - a.TotalDeaths;
} else if (val === "cases") {
return b.TotalConfirmed - a.TotalConfirmed;
} else if (val === "recovered") {
return b.TotalRecovered - a.TotalRecovered;
}
});
console.log(sortedResults);
setSortedCountries(sortedResults);
};
return (
<div className="all-container">
<p>Sort countries by the highest number of:</p>
<button onClick={() => sortResults("deaths")}>Deaths</button>
<button onClick={() => sortResults("cases")}>Cases</button>
<button onClick={() => sortResults("recovered")}>Recoveries</button>
<ul className="all-countries">
{sortedCountries.map((country, key) => {
return <li key={key}>{country.Country}</li>;
})}
</ul>
</div>
);
}
export default AllCountries;
这在 React 中有点问题,另一个解决方案是改用 useReducer。如下所示:
function reducer(state, action) {
return [...state, ...action];
}
function AllCountries({ countries }) {
const [sortedCountries, setSortedCountries] = useReducer(reducer, []);
useEffect(() => {
console.log(sortedCountries)
}, [sortedCountries])
const sortResults = (e, val) => {
e.preventDefault();
let sortedResults = countries.sort((a, b) => {
if (val === "deaths") {
return b.TotalDeaths - a.TotalDeaths;
} else if (val === "cases") {
return b.TotalConfirmed - a.TotalConfirmed;
} else if (val === "recovered") {
return b.TotalRecovered - a.TotalRecovered;
}
});
console.log(sortedResults);
setSortedCountries(sortedResults);
};
return (
<div className="all-container">
<p>Sort countries by the highest number of:</p>
<button onClick={(e) => sortResults(e, "deaths")}>Deaths</button>
<button onClick={(e) => sortResults(e, "cases")}>Cases</button>
<button onClick={(e) => sortResults(e, "recovered")}>Recoveries</button>
<ul className="all-countries">
{sortedCountries.map((country, key) => {
return <li key={key}>{country.Country}</li>;
})}
</ul>
</div>
);
}
export default AllCountries;
让 sortedResults = countries.sort
此行正在对国家属性进行排序并将 sortedResults 设置为该指针
让我们假设指针保存在内存中 |0001|为简单起见[=10=]
第一次点击后,函数被触发,prop 被排序,sortedResults 通过 setSortedCountries(设置状态)设置。
这会触发您想要的渲染,因为之前的状态未定义,现在状态指向 |0001|
当您的函数再次运行时,排序函数将触发,在 |0001| 上工作。 returns——你猜对了——|0001|但是使用新的排序数组。
当你第二次设置状态时,实际上并没有改变任何状态,因为之前的国家是|0001|。您要更改的国家/地区是 |0001|
那么我们能做什么我的好先生?
首先我需要你考虑一下这个问题,想一想你可以如何解决这个问题并尝试应用一些更改。
你可以尝试做的是将 countries 属性复制到一个具有相同值的新数组指针,然后对其进行排序,然后将 sortedCountries 状态设置为该列表。
这有意义吗?
顺便说一句,这也是出于类似的原因,如果您尝试直接在新对象状态上设置状态,则新对象状态将与您设置的状态完全相同。这里没有任何真正的魔法。 React 不会自动合并你以前的对象状态和你的新对象状态,除非你明确告诉它这样做。
从某种意义上说,你已经告诉 react 检查两个状态之间的差异,一个旧国家和一个新国家(在幕后用 Vdom),但是要做出反应,这两个国家没有区别。由于两个对象状态没有区别,因此不会有实际的 DOM 变化。
因此,您两次设置指针不会产生任何实际变化。
因此,您必须将状态设置为具有新值的实际新指针,以便反应虚拟 dom 可以比较两个状态(以前的国家/地区列表)和新的国家/地区列表。
希望对您有所帮助
-
Array.sort()
方法没有 return 新引用,它 return 是相同的引用。所以我假设在 sortedCountries
状态中存储了相同的 props.countries 引用,这就是为什么第二次单击按钮不设置状态(它是相同的引用),我可以给你简单的解决方案只是改变这个行 setSortedCountries(sortedResults)
与此 setSortedCountries([...sortedResults])
在这种情况下,sortedResults 的副本将传递给 setSortedCountries
(新参考)。
当我点击按钮对网站加载后的国家数据进行排序时,数据显示正确。但是当我想按不同的值再次对其进行排序时,数据不会更新,状态也不会更新,但是,该函数运行良好,因为我可以看到控制台中的结果已正确排序。这种奇怪行为的原因可能是什么?谢谢你的时间。
function AllCountries({ countries }) {
const [sortedCountries, setSortedCountries] = useState([]);
useEffect(() => {
console.log(sortedCountries)
}, [sortedCountries])
const sortResults = (val) => {
let sortedResults = countries.sort((a, b) => {
if (val === "deaths") {
return b.TotalDeaths - a.TotalDeaths;
} else if (val === "cases") {
return b.TotalConfirmed - a.TotalConfirmed;
} else if (val === "recovered") {
return b.TotalRecovered - a.TotalRecovered;
}
});
console.log(sortedResults);
setSortedCountries(sortedResults);
};
return (
<div className="all-container">
<p>Sort countries by the highest number of:</p>
<button onClick={() => sortResults("deaths")}>Deaths</button>
<button onClick={() => sortResults("cases")}>Cases</button>
<button onClick={() => sortResults("recovered")}>Recoveries</button>
<ul className="all-countries">
{sortedCountries.map((country, key) => {
return <li key={key}>{country.Country}</li>;
})}
</ul>
</div>
);
}
export default AllCountries;
这在 React 中有点问题,另一个解决方案是改用 useReducer。如下所示:
function reducer(state, action) {
return [...state, ...action];
}
function AllCountries({ countries }) {
const [sortedCountries, setSortedCountries] = useReducer(reducer, []);
useEffect(() => {
console.log(sortedCountries)
}, [sortedCountries])
const sortResults = (e, val) => {
e.preventDefault();
let sortedResults = countries.sort((a, b) => {
if (val === "deaths") {
return b.TotalDeaths - a.TotalDeaths;
} else if (val === "cases") {
return b.TotalConfirmed - a.TotalConfirmed;
} else if (val === "recovered") {
return b.TotalRecovered - a.TotalRecovered;
}
});
console.log(sortedResults);
setSortedCountries(sortedResults);
};
return (
<div className="all-container">
<p>Sort countries by the highest number of:</p>
<button onClick={(e) => sortResults(e, "deaths")}>Deaths</button>
<button onClick={(e) => sortResults(e, "cases")}>Cases</button>
<button onClick={(e) => sortResults(e, "recovered")}>Recoveries</button>
<ul className="all-countries">
{sortedCountries.map((country, key) => {
return <li key={key}>{country.Country}</li>;
})}
</ul>
</div>
);
}
export default AllCountries;
让 sortedResults = countries.sort
此行正在对国家属性进行排序并将 sortedResults 设置为该指针
让我们假设指针保存在内存中 |0001|为简单起见[=10=]
第一次点击后,函数被触发,prop 被排序,sortedResults 通过 setSortedCountries(设置状态)设置。
这会触发您想要的渲染,因为之前的状态未定义,现在状态指向 |0001|
当您的函数再次运行时,排序函数将触发,在 |0001| 上工作。 returns——你猜对了——|0001|但是使用新的排序数组。
当你第二次设置状态时,实际上并没有改变任何状态,因为之前的国家是|0001|。您要更改的国家/地区是 |0001|
那么我们能做什么我的好先生?
首先我需要你考虑一下这个问题,想一想你可以如何解决这个问题并尝试应用一些更改。
你可以尝试做的是将 countries 属性复制到一个具有相同值的新数组指针,然后对其进行排序,然后将 sortedCountries 状态设置为该列表。
这有意义吗?
顺便说一句,这也是出于类似的原因,如果您尝试直接在新对象状态上设置状态,则新对象状态将与您设置的状态完全相同。这里没有任何真正的魔法。 React 不会自动合并你以前的对象状态和你的新对象状态,除非你明确告诉它这样做。
从某种意义上说,你已经告诉 react 检查两个状态之间的差异,一个旧国家和一个新国家(在幕后用 Vdom),但是要做出反应,这两个国家没有区别。由于两个对象状态没有区别,因此不会有实际的 DOM 变化。
因此,您两次设置指针不会产生任何实际变化。
因此,您必须将状态设置为具有新值的实际新指针,以便反应虚拟 dom 可以比较两个状态(以前的国家/地区列表)和新的国家/地区列表。
希望对您有所帮助
-
Array.sort()
方法没有 return 新引用,它 return 是相同的引用。所以我假设在 sortedCountries
状态中存储了相同的 props.countries 引用,这就是为什么第二次单击按钮不设置状态(它是相同的引用),我可以给你简单的解决方案只是改变这个行 setSortedCountries(sortedResults)
与此 setSortedCountries([...sortedResults])
在这种情况下,sortedResults 的副本将传递给 setSortedCountries
(新参考)。