Skip to content

siblings useless/buggy re-render #477

@cyber-land

Description

@cyber-land

Premise, i'm a very beginner of this library so maybe i'm missing something.

The following code is a simpler version of my original code but still able to trigger (what i consider) a bug that happens when a function (connection_check) (not sure if the conditional return is necessary) render multiple other functions.
The problem source is that one of them modify a global variable (docs) and another read it.
The bug make the functions infinitely re-rendering (noticed by the infinite log of render_DocsBar, render_break, render_DocsBody) while render_connection_check only log once.

This probably means that one (probably DocsBody) of them trigger the re-render of its siblings functions but i wouldn't expect it since the others don't need to know about docs changes

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<script type="module">
		import van from "https://cdn.jsdelivr.net/gh/vanjs-org/van/public/van-1.6.0.min.js"

		const { div, br, p, button } = van.tags

		const docs = van.state([])
		van.derive(() => console.log("docs", docs.val))

		van.add(document.getElementById('root'), connection_check())

		function connection_check() {
			console.log("render_connection_check")
			const filters = van.state([])

			fetch(`https://dummyjson.com/c/dc48-b6a1-4cdd-afd6`)
				.then(response => response.json())
				.then(data => data === null ? filters.val = [] : filters.val = data)
				.catch(error => filters.val = [])

			return () => filters.val.length > 0
				? div(
					DocsBar(filters.val),
					_break(),
					DocsBody()
				)
				: p(`can't reach the server`)
		}

		function _break() {
			console.log("render_break")
			return br()
		}

		function DocsBar(_filters) {
			console.log("render_DocsBar")
			const value = van.state(5) // default value

			van.derive(() => {
				fetch(`https://dummyjson.com/posts?limit=${value.val}`)
					.then(response => response.json())
					.then(data => docs.val = data) // !
					.catch(error => docs.val = [])
			})

			return div(
				button({
					onclick: () => value.val = Math.floor(Math.random() * 5) + 1
				}, "click"),
				_filters.map(f => p(f))
			)
		}

		function DocsBody() {
			console.log("render_DocsBody")
			return div(docs.val.posts.map(d => d.title)) // !
		}
	</script>
</head>

<body>
	<div id="root"></div>
</body>

</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions