Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions packages/react-dom/src/__tests__/ReactServerRendering-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -664,4 +664,60 @@ describe('ReactDOMServer', () => {
require('react-dom');
}).not.toThrow();
});

it('includes a useful stack in warnings', () => {
function A() {
return null;
}

function B() {
return (
<font>
<C>
<span ariaTypo="no" />
</C>
</font>
);
}

class C extends React.Component {
render() {
return <b>{this.props.children}</b>;
}
}

function Child() {
return [<A key="1" />, <B key="2" />, <span ariaTypo2="no" />];
}

function App() {
return (
<div>
<section />
<span>
<Child />
</span>
</div>
);
}

expect(() => ReactDOMServer.renderToString(<App />)).toWarnDev([
'Invalid ARIA attribute `ariaTypo`. ARIA attributes follow the pattern aria-* and must be lowercase.\n' +
' in span (at **)\n' +
' in b (at **)\n' +
' in C (at **)\n' +
' in font (at **)\n' +
' in B (at **)\n' +
' in Child (at **)\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in App (at **)',
'Invalid ARIA attribute `ariaTypo2`. ARIA attributes follow the pattern aria-* and must be lowercase.\n' +
' in span (at **)\n' +
' in Child (at **)\n' +
' in span (at **)\n' +
' in div (at **)\n' +
' in App (at **)',
]);
});
});
34 changes: 18 additions & 16 deletions packages/react-dom/src/server/ReactPartialRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,12 @@ type toArrayType = (children: mixed) => FlatReactChildren;
const toArray = ((React.Children.toArray: any): toArrayType);

let currentDebugStack;
let currentDebugElementStack;

let getStackAddendum = () => '';
let describeStackFrame = element => '';

let validatePropertiesInDevelopment = (type, props) => {};
let setCurrentDebugStack = (stack: Array<Frame>) => {};
let pushElementToDebugStack = (element: ReactElement) => {};
let resetCurrentDebugStack = () => {};

if (__DEV__) {
Expand All @@ -88,22 +86,11 @@ if (__DEV__) {
};

currentDebugStack = null;
currentDebugElementStack = null;
setCurrentDebugStack = function(stack: Array<Frame>) {
const frame: Frame = stack[stack.length - 1];
currentDebugElementStack = ((frame: any): FrameDev).debugElementStack;
// We are about to enter a new composite stack, reset the array.
currentDebugElementStack.length = 0;
currentDebugStack = stack;
ReactDebugCurrentFrame.getCurrentStack = getStackAddendum;
};
pushElementToDebugStack = function(element: ReactElement) {
if (currentDebugElementStack !== null) {
currentDebugElementStack.push(element);
}
};
resetCurrentDebugStack = function() {
currentDebugElementStack = null;
currentDebugStack = null;
ReactDebugCurrentFrame.getCurrentStack = null;
};
Expand Down Expand Up @@ -388,6 +375,7 @@ function validateRenderResult(child, type) {
function resolve(
child: mixed,
context: Object,
debugElementStack: Array<ReactElement> | null,
): {|
child: mixed,
context: Object,
Expand All @@ -397,7 +385,7 @@ function resolve(
let element: ReactElement = (child: any);
let Component = element.type;
if (__DEV__) {
pushElementToDebugStack(element);
((debugElementStack: any): Array<ReactElement>).push(element);
}
if (typeof Component !== 'function') {
break;
Expand Down Expand Up @@ -773,10 +761,19 @@ class ReactDOMServerRenderer {
continue;
}
const child = frame.children[frame.childIndex++];
let debugElementStack = null;
if (__DEV__) {
setCurrentDebugStack(this.stack);
debugElementStack = ((frame: any): FrameDev).debugElementStack;
// We are about to enter a new composite stack, reset the array.
debugElementStack.length = 0;
}
out += this.render(child, frame.context, frame.domNamespace);
out += this.render(
child,
frame.context,
frame.domNamespace,
debugElementStack,
);
if (__DEV__) {
// TODO: Handle reentrant server render calls. This doesn't.
resetCurrentDebugStack();
Expand All @@ -789,6 +786,7 @@ class ReactDOMServerRenderer {
child: ReactNode | null,
context: Object,
parentNamespace: string,
debugElementStack: Array<ReactElement> | null,
): string {
if (typeof child === 'string' || typeof child === 'number') {
const text = '' + child;
Expand All @@ -805,7 +803,11 @@ class ReactDOMServerRenderer {
return escapeTextForBrowser(text);
} else {
let nextChild;
({child: nextChild, context} = resolve(child, context));
({child: nextChild, context} = resolve(
child,
context,
debugElementStack,
));
if (nextChild === null || nextChild === false) {
return '';
} else if (!React.isValidElement(nextChild)) {
Expand Down