We can use the `for()` method to render a list of items based on a reactive array. Lists in requery-js support both keyed and non-keyed rendering.
Written By Joel
Last updated About 1 month ago
Basic Usage
For simple lists of primitive values, you can use the non-keyed approach:
HTML
<my-component>
<div rq="item">
<span rq="title"></span>
</div>
</my-component>
JavaScript
defineComponent("my-component", {
store: {
todos: ["Learn requery", "Build app"]
},
setup(component, props, store) {
component.query("item").for(
() => store.todos,
(el, item) => {
el.query("title").text(() => item);
}
);
}
})
Object List
Lists often need to contain more than just a single value. Here's how to work with objects in a list:
HTML
<my-component>
<div rq="item">
<span rq="status"></span>
<span rq="title"></span>
</div>
</my-component>
JavaScript
defineComponent("my-component", {
store: {
todos: [
{
text: "Learn requery",
completed: true
},
{
text: "Build app",
completed: false
}
]
},
setup(component, props, store) {
component.query("item").for(
() => store.todos,
(el, todo) => {
el.query("title").text(() => todo.text);
el.query("status").text(() =>
todo.completed ? "✅" : "❌"
);
}
);
}
})
Keyed Lists
When rendering lists without passing a key function, requery-js uses an "in-place" update strategy. This means elements are updated in their current position, regardless of how the data has moved. While efficient, this approach isn't suitable when:
List items contain form inputs
You're animating list changes
You’re using 3rd party libraries in list items
To reorder the underlying DOM nodes when updating a list you can provide a key function.
Important
The key function should return primitive values (strings or numbers). Don't use objects as keys
defineComponent("my-component", {
store: {
todos: [
{
id: 1,
text: "Learn requery",
completed: false
},
{
id: 2,
text: "Build app",
completed: true
}
]
},
setup(component, props, store) {
component.query("item").for(
() => store.todos,
(todo) => todo.id, // Key function tells requery-js how to track items
(el, todo) => {
el.query("title").text(() => todo.text);
el.query("status").text(() =>
todo.completed ? "✅" : "❌"
);
}
);
}
})
Non-keyed vs. Keyed Lists
It's recommended to use a key function with for()
whenever possible, unless:
Your list contains only simple text or numbers
You specifically want in-place updates for performance
Array Change Detection
Mutation Methods
requery-js automatically detects the following array changes:
push() / pop()
shift() / unshift()
splice()
sort() / reverse()
Replacing an Array
Array updates can be done through direct mutations or by creating new arrays. Methods like push()
and splice()
modify the original array, while methods like filter()
and slice()
create new arrays. When using methods that return new arrays, you need to reassign the result:
store.todos = store.todos.filter((item) => item.completed)
Displaying Filtered/Sorted Results
When displaying filtered or sorted results, return the transformed array in your getter function:
HTML
<my-component>
<button rq="toggle-completed">Hide Completed</button>
<button rq="toggle-sort">Sort by Name</button>
<div rq="todo">
<span rq="status"></span>
<span rq="title"></span>
</div>
</my-component>
JavaScript
defineComponent('my-component', {
store: {
todos: [
{ id: 1, text: 'Learn requery', completed: false },
{ id: 2, text: 'Build app', completed: true },
],
hideCompleted: false,
sortByName: false,
},
setup(component, props, store) {
component.query('todo').for(
() => {
// Start with the original array
let result = store.todos;
// Apply filter if needed
if (store.hideCompleted) {
result = result.filter((todo) => !todo.completed);
}
// Apply sort if needed
if (store.sortByName) {
result = [...result].sort((a, b) => a.text.localeCompare(b.text));
}
return result;
},
(todo) => todo.id,
(el, todo) => {
el.query('title').text(() => todo.text);
el.query('status').text(() => (todo.completed ? '✅' : '❌'));
}
);
// Toggle buttons
component.query('toggle-completed').on('click', () => {
store.hideCompleted = !store.hideCompleted;
});
component.query('toggle-sort').on('click', () => {
store.sortByName = !store.sortByName;
});
},
});
Be careful with reverse()
and sort()
in your getter functions! These methods mutate the original array. Create a copy using the spread operator before applying these methods:
return [...todos].reverse()
Could not load article.
Could not load article.