GithubHelp home page GithubHelp logo

child-array re-use error about dyo HOT 14 CLOSED

Zolmeister avatar Zolmeister commented on June 9, 2024
child-array re-use error

from dyo.

Comments (14)

thysultan avatar thysultan commented on June 9, 2024 1

This probably has nothing to do with race conditions or useCallback and more with holding onto references of the virtual nodes instead of using a declarative approach.

i.e

Ripple = ->
  [$waves, setWaves] = useState []

  ripple = useCallback ->
    $wave =  [Math.random()]
    setWaves $waves.concat $wave
    window.requestAnimationFrame ->
      setWaves _.without $waves, $wave
  , [$waves]

  h 'div',
    className: 'ripple'
    onmousedown: ripple
    $waves.map(v => h('div', {}, v))

from dyo.

thysultan avatar thysultan commented on June 9, 2024 1

Yes, that was one of the breaking changes from v8 -> v9/dyo-v1, which carried over to dyo. It wasn't worth the complexity to support it since it's not idiomatic to the declarative paradigm.

from dyo.

thysultan avatar thysultan commented on June 9, 2024 1

Similar reason as to why we append empty in the current instalment https://github.com/dyo/dyo/blob/master/src/Element.js#L137 it acts as an anchor node for the fragment, and arrays act like fragments in order to be afforded a certain level of isolation from siblings, this can avoid key collision under certain conditions i.e in

h(div, {}, [h('h1', {key: 1}, 1)], [h('h1', {key: 1}, 1)])

Both heading are under separate namespaces(arrays) so can reuse the same key, this is more useful when you are using something like

h('div', {}, 
   arr1.map(v => h('h1', {key: v.id}, v.data)),
   arr2.map(v => h('h1', {key: v.id}, v.data))
)

...and not have to worry whether v.id in the two data source will collide.

I put null instead of empty() because they are effectively represent they same type of node vice-versa.

from dyo.

thysultan avatar thysultan commented on June 9, 2024

This is expected.

from dyo.

Zolmeister avatar Zolmeister commented on June 9, 2024

@thysultan How so? This worked in dio v8

from dyo.

Zolmeister avatar Zolmeister commented on June 9, 2024

@thysultan can this be detected easily to produce a better error message?
Edit: note that it does not throw in React

from dyo.

thysultan avatar thysultan commented on June 9, 2024

Looking at this closer: the following also resolves this issue:

  h 'div',
    className: 'ripple'
    onmousedown: ripple,
    [...$waves], 'or', ...$waves

from dyo.

thysultan avatar thysultan commented on June 9, 2024

If we change: https://github.com/dyo/dyo/blob/master/src/Element.js#L137 to

return iterable(value.concat(null), hash(index))

It should solve that issue. Current code reuses(direct assignment) the array which avoids creating a new array but concat could be just as fast/negligible.

from dyo.

Zolmeister avatar Zolmeister commented on June 9, 2024

Great
Also value.concat(null) appends a null (not sure if it matters). Use value.concat() instead.

Edit: value.slice() is fastest (for me) - https://jsperf.com/cloning-arrays/38

from dyo.

thysultan avatar thysultan commented on June 9, 2024

not sure if it matters

The append a null part is deliberate.

from dyo.

Zolmeister avatar Zolmeister commented on June 9, 2024

Why append null?

from dyo.

thysultan avatar thysultan commented on June 9, 2024

Better comparison of current(push) vs the proposed(concat): https://jsperf.com/concat-vs-inline-push

from dyo.

Zolmeister avatar Zolmeister commented on June 9, 2024

Perhaps running a more realistic benchmark would help understand the impact.
e.g. https://github.com/krausest/js-framework-benchmark

From a correctness standpoint I think mutation should be avoided.
Could you anchor the fragment by polluting its properties instead?

from dyo.

thysultan avatar thysultan commented on June 9, 2024

Yes, testing the whole h/createElement function variants would be the better comparison.

from dyo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.