chenglou / chenglou/react-state-stream

Conversion between JS and clj doesn't preserve key order, messing up this.props.children

Open
#6 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
357
Forks
19
PR merge metrics
No merged PRs in 30d

Description

I can't figure out why this happens.

I copy-pasted third example, but I wanted to play with text inputs. For starters, I tried simplest example possible: I wanted to animate `, world` away and back inside a `

`.

This is what I did:

``` js
var App4 = React.createClass({
getInitialState: function () {
return { text: 'Hello' };
},

handleClick: function () {
if (this.state.text === 'Hello') {
this.setState({ text: 'Hello, world' });
} else {
this.setState({ text: 'Hello' });
}
},

render: function() {
return (



{this.state.text.split('').map(function (l, i) {
return {l};
})}


);
}
});
```

However, this refused to work with `Container`: items would animate but children order would get messed up when I click.

I soon realized that [this line](https://github.com/gaearon/react-state-stream/blob/e78c21d08578a7d488aa82b6dfe9e2953642e70b/App4.jsx#L60) messes up child order:

``` js
var children = M.js_to_clj(/*toObj(*/nextProps.children/*)*/);
```

(namely, I had to remove `toObj` call)

Similarly, I had to change the loop in `Container#render` to enumerate an array instead:

``` js
/*
for (var key in state.children) {
if (!state.children.hasOwnProperty(key)) {
continue;
}
var s = {
top: state.configs[key].top,
width: state.configs[key].width,
opacity: state.configs[key].opacity,
position: 'relative',
overflow: 'hidden',
WebkitUserSelect: 'none',
};
children.push(
{state.children[key]}
);
}
*/

for (var index in state.children) {
if (!state.children.hasOwnProperty(index)) {
continue;
}

// Why do I have to do this?
var key = '.$' + state.children[index].key;

var s = {
top: state.configs[key].top,
width: state.configs[key].width,
opacity: state.configs[key].opacity,
position: 'relative',
overflow: 'hidden',
WebkitUserSelect: 'none',
};
children.push(
{state.children[index]}
);
}
```

Why does this happen when going over characters? It's not like this is _too_ different from your App3 example.

You can play with it [in this branch](https://github.com/gaearon/react-state-stream/tree/app4-experiment-against-upstream).

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with App4.jsx at the linked conversion line and inspect Container#render, using the app4-experiment-against-upstream branch to reproduce the character-animation case. Trace how nextProps.children is converted and iterated; done means child order remains correct without requiring the reported array workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure, javascript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.