我写了一个JavaScript脚本,它模拟了一个“项目比较器”,用户可以通过一系列用户输入创建一个排名列表。
我正在尝试构建一个简单的React应用程序,将此逻辑转换为用户界面。然而,由于我是React的新手,我很难获得一个功能正常的应用程序,我担心我没有使用正确的方法。任何帮助将不胜感激。
下面是包含我试图复制的逻辑的JavaScript代码:
const readline = require('readline-sync');
const items = ["A", "B", "C", "D", "E"];
let rankedListCount = 1;
// For each item, use a binary search approach to determine its spot in the list
for (let i = 1; i < items.length; i++) {
const item = items[i];
console.log(`Comparing ${item} to the existing list...`);
let left = 0;
let right = i - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const comparison_item = items[mid];
const preference = readline.question(`Do you prefer ${item} or ${comparison_item}? Enter 1 or 2: `);
if (preference === "1") {
right = mid - 1;
} else {
left = mid + 1;
}
}
const index = left;
items.splice(i, 1);
items.splice(index, 0, item);
rankedListCount++;
console.log(`Inserted ${item} at position ${index}\n`);
console.log("Your current ranking of the items is:");
for (let i = 0; i < rankedListCount; i++) {
console.log(`${i+1}) ${items[i]}`);
}
}
console.log("Your final ranking of the items is:");
for (let i = 0; i < items.length; i++) {
console.log(`${i+1}) ${items[i]}`);
}
这是我的React代码的当前状态。我希望用户能够按下按钮来完成比较,并有真实的更新的排名列表。
首先,我的选项是“选择哪个项目更好:”,有按钮说B和A和排名列表A-E。如果我点击其中一个按钮,什么也不会发生。
如果我再次单击它,按钮的内容会消失,排名列表也会消失。
import React, { useEffect, useState } from 'react';
const ItemComparator = () => {
const [rankedItemList, setRankedItemList] = useState(['A', 'B', 'C', 'D', 'E']);
const [rankedItemsCount, setRankedItemsCount] = useState(1);
const [primaryItem, setPrimaryItem] = useState(rankedItemList[1]);
const [comparisonItem, setComparisonItem] = useState(rankedItemList[0]);
const [leftIndex, setLeftIndex] = useState(0);
const [rightIndex, setRightIndex] = useState(rankedItemsCount-1);
const [midIndex, setMidIndex] = useState(Math.floor((leftIndex + rightIndex) / 2));
function handleSelection(preferredItem) {
if (preferredItem === 'primary') {
setRightIndex(midIndex-1);
} else {
setLeftIndex(midIndex+1);
}
if (leftIndex > rightIndex) {
setRankedItemList(rankedItemList.splice(rankedItemsCount, 1));
setRankedItemList(rankedItemList.splice(leftIndex, 0, primaryItem));
setRankedItemsCount(rankedItemsCount+1);
setPrimaryItem(rankedItemList[rankedItemsCount]);
setLeftIndex(0);
setRightIndex(rankedItemsCount-1);
setMidIndex(Math.floor((leftIndex + rightIndex) / 2));
setComparisonItem(rankedItemList[midIndex]);
}
}
return (
<div>
<h1>Item Comparator</h1>
<p>Select which item is better:</p>
<div>
<button onClick={() => handleSelection('primary')}>{rankedItemList[rankedItemsCount]}</button>
<button onClick={() => handleSelection('comparison')}>{rankedItemList[midIndex]}</button>
</div>
<h2>Comparison List</h2>
<ol>
<li>{rankedItemList[0]}</li>
<li>{rankedItemList[1]}</li>
<li>{rankedItemList[2]}</li>
<li>{rankedItemList[3]}</li>
<li>{rankedItemList[4]}</li>
</ol>
</div>
);
}
export default ItemComparator;
1条答案
按热度按时间11dmarpk1#
您可能误解了
useState
的工作原理。你不能仅仅把它作为一个参考值。每次调用状态设置器(例如
setRankedItemList
)时,都在更新react状态。通过调用
您将覆盖
rankedItemList
状态两次。React是“聪明的”,可以捆绑状态更新以提高性能,这就是为什么你会看到一些奇怪的行为。为了获得你期望的行为,你可以在
handleSelection
方法中使用本地或引用值。例如,
leftIndex
和rightIndex
可以是一个常数,每次调用handleSelection
方法时都会计算出来,如下所示:此外,在再次更新状态之前,应计算一次新的排名项
另外,您处理显示
rankedItemList
的方式与您在react
中执行此操作的方式不同,请查看the docs