ReactJS, как сопоставить массив на основе порядка другого массива

Мне помог ответ в Unmitigated, если вы ищете в Google, прокрутите вниз

заказ: [ "567", "645", "852", "645", "852", "852", ]

база данных: [ { "userId": 567, "userName": "tjk23", "department": "Sales", "remarks": "" }, { "userId": 645, "userName": "gfn23", "department": "Sales", "remarks": "" }, { "userId": 852, "userName": "dan24", "department": "Sales", "remarks": "", } ]

В настоящее время он отлично отображает массив базы данных, но отображает только 3 карты DisplayCard. Мне нужно, чтобы он отображался 6 раз, а также в порядке массива 6 в порядке

{database.map((data, index) => { return <DisplayCard data = {data} key = {index}/> })}

Как сделать так, чтобы он отображался с использованием последовательности массива заказов, не меняя слишком много кода? Поскольку DisplayCard используется в нескольких местах, я бы не хотел ее изменять.

я пытался использовать

{order.map((database.data, index) => { return <DisplayCard data = {database.data} key = {index}/> })}

и ожидал, что он будет использовать последовательность массива заказов и получать данные из соответствующего идентификатора пользователя в массиве базы данных

Но то, что на самом деле получилось, это ошибка, но я не знаю, почему

Редактировать для Unmitigated: Вот минимально воспроизводимый пример, я удалил вызов API и внешнюю ссылку на DisplayCard, и все уместилось в этом фрагменте.

export function Minimal() {
    var lookup;

    const order= [ "567", "645", "852", "645", "852", "852", ];

    const database = [ { "userId": 567, "userName": "tjk23", "department": "Sales", "remarks": "" }, { "userId": 645, "userName": "gfn23", "department": "Sales", "remarks": "" }, { "userId": 852, "userName": "dan24", "department": "Sales", "remarks": "", } ];
    
    function DisplayCard({data}) {
        return <div>{data.userId}</div>;
      }

    return (<>

    {database?.length > 0
        ? lookup = Object.fromEntries(database.map(o => [o.userId, o]))
        (
            <>
                {order.map((userId, index) => {
                    return <DisplayCard data = {lookup[userId]} key = {index} />                  
                })}     
            </>
        ) :
        (
            <div className = "empty">
                <h2>No records found</h2>
            </div>
        )}
    
</>)}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете создать объект, который сопоставляет каждый userId с объектом в массиве, а затем получать доступ к значениям из этого объекта поиска при использовании order.

let lookup = Object.fromEntries(database.map(o => [o.userId, o]));
// ...
{order.map((id, index) => <DisplayCard data = {lookup[id]} key = {index}/>)}

Пример:

function DisplayCard({data}) {
  return <div>{data.userName}</div>;
}

function App() {
  let order = [ "567", "645", "852", "645", "852", "852", ];
  let [database, setDatabase] = React.useState([ { "userId": 567, "userName": "tjk23", "department": "Sales", "remarks": "" }, { "userId": 645, "userName": "gfn23", "department": "Sales", "remarks": "" }, { "userId": 852, "userName": "dan24", "department": "Sales", "remarks": "", } ]);
  let lookup = Object.fromEntries(database.map(o => [o.userId, o]));
  return (
    <div>
      {order.map((id, index) => <DisplayCard data = {lookup[id]} key = {index}/>)}
      <button onClick = {() => setDatabase([{userId: 567, userName: 'changed 567'}, {userId: 645, userName: 'changed 645'}, {userId: 852, userName: 'changed 852'}])}>Change state</button>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
<script crossorigin src = "https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src = "https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id = "root"></div>

DisplayCard.jsx: 10 Uncaught TypeError: Не удается прочитать свойства undefined (чтение «userName») Я все еще пытаюсь понять, что пошло не так, но это ошибка, которую я получил, когда сразу вставил ваш код

wynnawinner 06.04.2023 05:40

@wynnawinner У вас есть идентификаторы, которых нет в order?

Unmitigated 06.04.2023 05:46

@wynnawinner Я обновил свой ответ фрагментом, показывающим, что код работает. Вероятно, в вашем коде есть проблема.

Unmitigated 06.04.2023 05:50

Нет, массив базы данных получен из массива заказов через аксиомы, это невозможно.

wynnawinner 06.04.2023 06:02

@wynnawinner Вы можете видеть, что код работает во фрагменте, учитывая информацию, указанную в вопросе. Если это не работает с вашей стороны, предоставьте минимально воспроизводимый пример, демонстрирующий проблему.

Unmitigated 06.04.2023 06:03

Я просто определил все локально и сделал минимальный воспроизводимый пример в редактировании вопроса.

wynnawinner 06.04.2023 06:19

@wynnawinner Проблема в том, что вы определили lookup не в том месте. Вам нужно объявить его как отдельную переменную. Правильное определение database как const lookup = Object.fromEntries(database.map(o => [o.userId, o])); сработает.

Unmitigated 06.04.2023 06:21

Вы имеете в виду просто перемещение строки поиска var после строки базы данных const, верно? Это ошибка Uncaught TypeError: невозможно прочитать свойства неопределенного (чтение «567») Minimal.js

wynnawinner 06.04.2023 06:25

@wynnawinner Нет, я имею в виду полное удаление var lookup и вместо этого const lookup = Object.fromEntries(database.map(o => [o.userId, o])); после определения database. НЕ добавляйте lookup = Object.fromEntries(database.map(o => [o.userId, o])) внутри JSX. (В настоящее время он стоит после database?.length > 0 ?, что неверно и должно быть удалено.) Посмотрите, как lookup определяется и используется в примере фрагмента моего ответа.

Unmitigated 06.04.2023 06:27

Это работает таким образом, но мне нужно, чтобы поиск менялся каждый раз, когда изменяется массив базы данных.

wynnawinner 06.04.2023 06:36

@wynnawinner Как определение lookup после database не достигает этого? Просто определите его внутри компонента, а не внутри JSX, и он будет меняться при каждом рендеринге, если database изменится.

Unmitigated 06.04.2023 06:37

Поскольку база данных является состоянием использования и будет меняться без перезагрузки страницы, которая вызовет код поиска, если я укажу место, которое вы мне сказали. Вот почему я подумал вставить фрагмент jsx, чтобы при обновлении массива базы данных поиск var снова назначался

wynnawinner 06.04.2023 06:41

@wynnawinner Когда вы устанавливаете состояние, компонент перерисовывается, поэтому код внутри запускается снова. Таким образом, правильно определить lookup внутри компонента.

Unmitigated 06.04.2023 06:42

@wynnawinner Я обновил фрагмент примера в своем ответе, чтобы показать, что он работает с состоянием.

Unmitigated 06.04.2023 06:45

Оооо, мне очень жаль, я думал, что константа поиска не может измениться в этой позиции, и только код в jsx {database?.length...} будет перерисовываться и выполняться повторно из-за изменения состояния базы данных useState?.length, а не всего Минимальный (). Вот и подумал поставить его туда. Спасибо!!!

wynnawinner 06.04.2023 06:56

«У вас есть идентификаторы, которые не существуют по порядку?»

wynnawinner 25.04.2023 21:13

при обновлении заказа требуется некоторое время для возврата запроса на выборку, поэтому в то время, когда он выполняет поиск с использованием массива ids, это приведет к сбою моего реагирующего приложения, потому что поиск будет обновляться быстрее, чем возвращаемый запрос на выборку

wynnawinner 25.04.2023 21:15
{
  order.map((id, index) => {
    const target = datebase.find(item => item.userId === id)
    return target ? <DisplayCard data = {target} key = {index} /> : null
  })
}

Я пробовал, но, кажется, всегда возвращает нулевую часть. (Сначала ничего не возвращалось, но я заменил ноль на "тест", и все отображалось "тест")

wynnawinner 06.04.2023 05:56

Может быть, вам следует заменить «===» на «==»?

XiaoMan 09.04.2023 14:26

То, что вам действительно нужно, это не карта, это фильтрация массива базы данных. Метод карты не используется, как вы думаете, см. определение: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

Я твердо верю, что это способ без слишком большого изменения кода.

Шаг 1: Отфильтруйте массив базы данных в соответствии с идентификаторами в массиве заказов

Шаг 2: Теперь вы можете использовать отфильтрованный массив базы данных

let resultsFiltered = database.filter(item => order.includes(item.userId))
    
{resultsFiltered.map((data, index) => { return <DisplayCard data = {data} key = {index}/>})}

Другие вопросы по теме