Skip to content
This repository has been archived by the owner on Aug 19, 2022. It is now read-only.

Commit

Permalink
Bug fix: Render array of elements (#979)
Browse files Browse the repository at this point in the history
Bug fix: render an array of elements

* handle array child elements; ensure that extraStateKeyMap is cleaned up

* Add regression test for render children.
  • Loading branch information
chrisbolin authored Mar 29, 2018
1 parent 26034a3 commit 7ee95cb
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Radium Changelog

## Unreleased
- Fix `render` methods that return array of children. (#950)

## 0.23.0 (March 15, 2018)
- Support ES7 arrow functions for React class methods. (#738)

Expand Down
33 changes: 32 additions & 1 deletion src/__tests__/radium-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,38 @@ describe('Radium blackbox tests', () => {
expect(div.style.color).to.equal('red');
});

// Regression test: https://github.com/FormidableLabs/radium/issues/950
it('works with array children', () => {
class TestComponent extends Component {
render = () => {
return [
<div key="key0" style={{color: 'blue', ':hover': {color: 'red'}}}>
{this.props.children}
</div>,
<div key="key1" style={{color: 'yellow', ':hover': {color: 'green'}}}>
two
</div>
];
};
}

const Wrapped = Radium(TestComponent);
const output = TestUtils.renderIntoDocument(<Wrapped>hello world</Wrapped>);

const divs = getElements(output, 'div');

expect(divs[0].style.color).to.equal('blue');
expect(divs[0].getAttribute('data-radium')).to.equal('true');
expect(divs[0].innerText).to.equal('hello world');
TestUtils.SimulateNative.mouseOver(divs[0]);
expect(divs[0].style.color).to.equal('red');

expect(divs[1].style.color).to.equal('yellow');
expect(divs[1].innerText).to.equal('two');
TestUtils.SimulateNative.mouseOver(divs[1]);
expect(divs[1].style.color).to.equal('green');
});

it('works fine if passing null, undefined, or false in style', () => {
const TestComponent = Radium(() => (
<div style={{background: undefined, border: false, color: null}} />
Expand Down Expand Up @@ -833,7 +865,6 @@ describe('Radium blackbox tests', () => {
</ContextGivingWrapper>
);
const div = getElement(output, 'div');

expect(div.style.color).to.equal('blue');
expect(div.innerText).to.equal('hello world');

Expand Down
36 changes: 30 additions & 6 deletions src/resolve-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,31 @@ resolveStyles = function(
);
}

if (Array.isArray(renderedElement) && !renderedElement.props) {
const elements = renderedElement.map(element => {
// element is in-use, so remove from the extraStateKeyMap
if (extraStateKeyMap) {
const key = getStateKey(element);
delete extraStateKeyMap[key];
}

// this element is an array of elements,
// so return an array of elements with resolved styles
return resolveStyles(
component,
element,
config,
existingKeyMap,
shouldCheckBeforeResolve,
extraStateKeyMap
).element;
});
return {
extraStateKeyMap,
element: elements
};
}

// ReactElement
if (
!renderedElement ||
Expand All @@ -400,8 +425,10 @@ resolveStyles = function(
return {extraStateKeyMap, element: renderedElement};
}

const children = renderedElement.props.children;

const newChildren = _resolveChildren({
children: renderedElement.props.children,
children,
component,
config,
existingKeyMap,
Expand All @@ -425,12 +452,9 @@ resolveStyles = function(
});

// If nothing changed, don't bother cloning the element. Might be a bit
// wasteful, as we add the sentinal to stop double-processing when we clone.
// wasteful, as we add the sentinel to stop double-processing when we clone.
// Assume benign double-processing is better than unneeded cloning.
if (
newChildren === renderedElement.props.children &&
newProps === renderedElement.props
) {
if (newChildren === children && newProps === renderedElement.props) {
return {extraStateKeyMap, element: renderedElement};
}

Expand Down
30 changes: 30 additions & 0 deletions test/radium-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,34 @@ describe('Radium blackbox SSR tests', () => {
);
});
});

describe('render scenarios', () => {
// Regression test: https://github.com/FormidableLabs/radium/issues/950
it('handles rendered child array', () => {
class Composed extends React.Component {
render() {
return [
React.createElement('div', {
key: 0,
style: {
color: 'blue'
}
}),
React.createElement('div', {
key: 1,
style: {
color: 'red'
}
})
];
}
}

const rendered = render(Radium(Composed));
expect(rendered).to.contain(
'<div style="color:blue" data-radium="true"></div>' +
'<div style="color:red" data-radium="true"></div>'
);
});
});
});

0 comments on commit 7ee95cb

Please sign in to comment.