Complex component first time loading
See original GitHub issueI’m building a complex unicorn component for a page. The case is list of audios in a table as image below.
Here my python code.
from django.core.paginator import Paginator
from django.utils.translation import ugettext_lazy as _ # noqa
from django_unicorn.components import UnicornView
from dashboard.models import Document
class AudioLibraryView(UnicornView):
first_load = False
items_per_page = 10
title = ''
page_index = 1
paginator = None
page = None
class Meta:
exclude = ()
javascript_exclude = ('paginator', 'page', 'http_request', '_search_documents')
# def hydrate(self):
# print('first_load', self.first_load)
# if self.first_load is True:
# self._search_documents()
# self.first_load = False
def _search_documents(self):
qs = Document.objects.get_documents_by_user(
user=self.request.user
)
if self.title:
qs = qs.filter(title__icontains=self.title)
paginator = Paginator(qs, self.items_per_page)
self.paginator = paginator
self.page = paginator.page(self.page_index)
return self.page
def search_documents(self):
self._search_documents()
def next_page(self):
self.page_index += 1
self._search_documents()
def previous_page(self):
self.page_index = max(self.page_index - 1, 1)
self._search_documents()
The problem that I found was that the function search_documents
was called multiples times before the component render.
That’s happened because I put a for loop calling search_documents
and also the Pesquisa button to call search_documents
.
To solve this problem, I bind search_documents
only on Pesquisa and the for loop
iterates over page.object_list
, that is loaded on _search_documents
.
However, I needed to put the fallowing code to load the table at first time load.
<script type="text/javascript">
(function(){
setTimeout(function(){document.getElementById('button-get-documents').click();}, 500);
})();
</script>
My question is if there a native way to do this load at first time.
Here my unicorn html component code.
<div>
<div class="inline-flex flex-row max-w-sm md:max-w-md mb-6 items-center">
<input unicorn:model="page_index" type="hidden" value="{{page_index}}">
<div class="">
<label class="">
<input unicorn:model.defer="title" type="text" name="name" class="border-radius-none mt-1 w-full rounded-md border-neutral-300 focus:border-primary-800" placeholder="{% trans "Title" %}" maxlength="100" required="" autocomplete="off">
</label>
</div>
<div class="ml-4">
<a id="btn-search-documents" unicorn:click="search_documents" class="flex cursor-pointer justify-between px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-primary-600 border border-transparent rounded-full active:bg-primary-600 hover:bg-primary-500 focus:outline-none focus:shadow-outline-primary">
<span class="jam jam-search mr-1 text-lg"></span>
<span>{% trans "Search" %}</span>
</a>
</div>
</div>
<div class="w-full overflow-hidden rounded-lg border-2 shadow-xs">
<div class="w-full overflow-x-auto">
<table class="w-full table-auto whitespace-no-wrap">
<thead>
<tr class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800">
<th class="px-4 py-3">{% trans "Title" %}</th>
<th class="px-4 py-3">{% trans "Voice" %}</th>
<th class="px-4 py-3">{% trans "Speed" %}</th>
<th class="px-4 py-3">{% trans "Created" %}</th>
<th class="px-4 py-3">{% trans "Status" %}</th>
<th class="px-4 py-3">{% trans "Pages" %}</th>
<th class="px-4 py-3">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
{% for doc in page.object_list %}
<tr class="dark:text-gray-400">
<td class="px-3 py-2">
<div class="flex items-center text-sm">
<div>
<a class="link text-primary-500" href="/html/soarvoice/soarvoice.html?text-editor&doc_id={{doc.id}}"><span class="font-semibold">{{doc.title}}</span></a>
</div>
</div>
</td>
<td class="px-3 py-2 text-sm">
{{doc.voice.name}}
</td>
<td class="px-3 py-2 text-sm">
{{doc.get_speed_display}}
</td>
<td class="px-3 py-2 text-sm">
{{doc.created|date:"d/m/Y"}}
</td>
<td class="px-3 py-2 text-sm">
{% if doc.status %}
<span class="px-2 py-1 font-semibold leading-tight text-primary-700 bg-primary-100 rounded-full dark:bg-primary-700 dark:text-primary-100">{% trans "Done" %}</span>
{% else %}
<span class="inline px-2 py-1 font-semibold leading-tight text-orange-700 bg-orange-100 rounded-full dark:bg-orange-700 dark:text-primary-100">{% trans "Working" %}
</span>
{% endif %}
</td>
<td class="px-3 py-2 text-sm">
{{doc.created|date:"d/m/Y"}}
</td>
<td class="px-3 py-2 text-sm">
<div class="inline-flex">
<button unicorn:click="delete({{doc.id}})" class="mr-2 flex px-3 py-1 text-xs font-bold leading-5 text-white transition-colors duration-150 bg-primary-600 border border-transparent rounded-md active:bg-primary-600 hover:bg-primary-700 focus:outline-none focus:shadow-outline-primary">
<span class="text-xl jam jam-play"></span>
{% trans "Play" %}
</button>
<button unicorn:click="delete({{doc.id}})" class="px-3 py-1 text-xs font-bold leading-5 text-white transition-colors duration-150 bg-red-600 border border-transparent rounded-md active:bg-red-600 hover:bg-red-700 focus:outline-none focus:shadow-outline-red">
{% trans "Delete" %}
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800">
<span class="flex items-center col-span-3">
{{ page_index }} {% trans "of" %} {{paginator.num_pages}}
</span>
<span class="col-span-2"></span>
<!-- Pagination -->
<span class="flex col-span-4 mt-2 sm:mt-auto sm:justify-end">
<nav aria-label="Table navigation">
<ul class="inline-flex items-center">
<li>
<button unicorn:click="previous_page" class="flex align-middle px-3 py-1 rounded-md rounded-l-lg focus:outline-none focus:shadow-outline-purple" aria-label="Previous">
<svg aria-hidden="true" class="w-5 h-5 fill-current" viewBox="0 0 20 20">
<path d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" fill-rule="evenodd"></path>
</svg>
<span class="inline text-md">{% trans "Previous" %}</span>
</button>
</li>
<li>
<button unicorn:click="next_page" class="flex align-middle px-3 py-1 rounded-md rounded-r-lg focus:outline-none focus:shadow-outline-purple" aria-label="Next">
<span class="inline text-md">{% trans "Next" %}</span>
<svg class="w-5 h-5 fill-current" aria-hidden="true" viewBox="0 0 20 20">
<path d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" fill-rule="evenodd"></path>
</svg>
</button>
</li>
</ul>
</nav>
</span>
</div>
</div>
</div>
<script type="text/javascript">
(function(){
setTimeout(function(){document.getElementById('btn-search-documents').click();}, 500);
})();
</script>
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (4 by maintainers)
Top Results From Across the Web
How to Load Data Easily With React Hooks - Medium
First things first, let's build out a new functional component that we'll ... load data each time a prop changes or only on...
Read more >Lazy loading React components - LogRocket Blog
The concept of lazy loading is simple: initialize objects that are critical to the user interface first and quietly render noncritical items ...
Read more >React useEffect to have different behavior on first load and ...
When you call useEffect() you can return a clean-up function. That cleanup function gets called when the component is unmounted.
Read more >Run useEffect Only Once - CSS-Tricks
Run useEffect Only Once ... React has a built-in hook called useEffect. Hooks are used in function components. The Class component comparison to ......
Read more >How We Reduced Our React App's Load Time by 60% - InfoQ
The first step to optimising is measuring. Only once we identified the bottlenecks could we eliminate them. Chrome DevTools offers powerful ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@adamghill, I think you can close this issue since there no problem on
django-unicorn
. Thanks.Interesting! Yes, I use
pickle
to cache some parts of the component and it can’t pickleHttpRequest
(I end up dealing with requests in my code to make them cacheable). I’ll see if maybe there is a better error message I could surface to make it more obvious that things might break.