#javascript #reactjs
#javascript #reactjs
Вопрос:
Я пытаюсь создать компонент глоссария в React, который позволяет мне фильтровать только термины глоссария, которые мне нужны для изучения конкретного модуля. У меня есть два разных массива данных, один для терминов глоссария и один для единиц измерения. Это мой файл данных глоссария:
{
id: 1,
order: 1,
term: "Mario",
content: "It's a meeee"
},
{
id: 2,
order: 2,
term: "Luigi",
content: "Okie dokie!"
},
{
id: 3,
order: 3,
term: "Peach",
content: "Thank you, Mario!"
},
{
id: 4,
order: 4,
term: "Bowser",
content: "No one asks for a trap faster than a plumber!"
},
{
id: 5,
order: 5,
term: "Ganondorf",
content: "How dare you attempt to wound the Demon King!"
}
Это мой файл данных единицы измерения:
const units = [
{
order: 1,
glossaryTermsRequired: [1,2,3]
},
{
order: 2,
glossaryTermsRequired: [4,5]
}
]
Теперь это мой компонент глоссария:
const Glossary = ({ glossaryId, glossaryTerm }) => {
const [isOpen,setIsOpen]=useState(false)
useEffect(()=>{
insertGlossaryTerm()
})
return (
<>
<span onClick={()=>setIsOpen(true)} className="glossaryTerm">{glossaryTerm}</span>
<Sidebar closeSidebar={()=>setIsOpen(false)} isOpen={isOpen}/>
</>
);
Компонент глоссария принимает два реквизита: идентификатор и строку термина. Моя цель — щелкнуть по глоссарию и показать эти необходимые термины на боковой панели, которая откроется по щелчку. Теперь, например, если я нажму на термин Bowser, как я могу показать все термины для этого требуемого блока? (4,5 блок 2)
Спасибо, ребята
Комментарии:
1. Я не понимаю, в чем логика. Итак, если я нажму на «Bowser», алгоритм должен понять, что у Bowser есть id == 4 , затем найдите, где это слово встречается внутри массива единиц и извлеките эти значения?
2. точно, если я нажму на Bowser, я хотел бы увидеть все остальные глоссарии, которые есть в этом массиве, так что (4,5 = Bowser и Ganondorf)
Ответ №1:
const Glossary = ({ glossaryId, glossaryTerm }) => {
const [isOpen,setIsOpen]=useState(false);
const [sidebarTerms, setSidebarTerms] = useState([]);
useEffect(()=>{
if (isOpen)
insertGlossaryTerm()
}, [isOpen])
const insertGlossaryTerm = () => {
let unit = units.find(u => u.glossaryTermsRequired.indexOf(4)>=0);
if (unit) {
let termArray = unit.glossaryTermsRequired.map(id => elements[id].term);
setSidebarTerms(termArray);
}
}
return (
<>
<span onClick={()=>setIsOpen(true)} className="glossaryTerm">{glossaryTerm}</span>
<Sidebar closeSidebar={()=>setIsOpen(false)} isOpen={isOpen} terms={sidebarTerms}/>
</>
);
Объяснение:
- создано состояние для управления связанными терминами. Это список строк
- при
span
нажатии открывается боковая панель - Эффект использования запускается при изменении
isOpen
состояния. Выполняет поиск связанных терминов и сохраняет их в связанном состоянии - состояние связано с боковой панелью, поэтому оно получило через реквизиты соответствующие термины, готовые к отображению
Чтобы заставить его работать, вам нужно создать глобальный объект в моем примере, который называется elements
, то есть объект JSON с ключом-значением, где ключом является id
элемент, а значением — сам элемент.
Пример:
{
'1': {
id: 1,
order: 1,
term: "Mario",
content: "It's a meeee"
},
'2': {
id: 2,
order: 2,
term: "Luigi",
content: "Okie dokie!"
},
...
}
Это позволяет вашему приложению перебирать весь список элементов, чтобы найти элементы с правильным идентификатором.
Затем вам также нужно, чтобы units
объект был видимым.
Улучшения:
- вы можете запустить функцию insertGlossaryTerm() раньше, чем функцию isOpen()
- если термины могут состоять более чем из одной единицы, тогда вам нужно заменить .найти функцию с помощью .filter
Комментарии:
1. Если вы использовали метод find, единицы измерения должны находиться внутри массива, а не объекта json, верно?
2. @Robozombie да, оба . find и .filter являются функциями массивов. Таким образом, единицы измерения должны быть массивом элементов. В вашем случае элементы — это объекты unit, которые вы описали в своем вопросе (так что с
order
glossaryTermsRequired
ключами и)3. Спасибо за ответ. У меня бесконечный цикл внутри useEffect, даже если вы передали isOpen внутри массива. Я заметил, что однажды я изменил indexOf на свой glossaryID
4. итак, с 4 в indexOf проблем нет, но если вы передаете
glossaryId
параметры, продолжается бесконечный цикл? Довольно странно… Можете ли вы опубликовать свой код на скрипке?5. Исправлено, мне пришлось разобрать glossaryId, который был строкой Спасибо за вашу помощь, теперь работает безупречно