/** @flow */
import * as React from 'react';
import {Fragment, useEffect, useRef, useState} from 'react';
// $FlowFixMe[missing-local-annot]
function WarnDuringRender({children = null}) {
console.warn('This warning fires during every render');
return children;
}
// $FlowFixMe[missing-local-annot]
function WarnOnMount({children = null}) {
useEffect(() => {
console.warn('This warning fires on initial mount only');
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function WarnOnUpdate({children = null}) {
const didMountRef = useRef(false);
useEffect(() => {
if (didMountRef.current) {
console.warn('This warning fires on every update');
} else {
didMountRef.current = true;
}
});
return children;
}
// $FlowFixMe[missing-local-annot]
function WarnOnUnmount({children = null}) {
useEffect(() => {
return () => {
console.warn('This warning fires on unmount');
};
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorDuringRender({children = null}) {
console.error('This error fires during every render');
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorOnMount({children = null}) {
useEffect(() => {
console.error('This error fires on initial mount only');
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorOnUpdate({children = null}) {
const didMountRef = useRef(false);
useEffect(() => {
if (didMountRef.current) {
console.error('This error fires on every update');
} else {
didMountRef.current = true;
}
});
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorOnUnmount({children = null}) {
useEffect(() => {
return () => {
console.error('This error fires on unmount');
};
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorAndWarningDuringRender({children = null}) {
console.warn('This warning fires during every render');
console.error('This error fires during every render');
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorAndWarningOnMount({children = null}) {
useEffect(() => {
console.warn('This warning fires on initial mount only');
console.error('This error fires on initial mount only');
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorAndWarningOnUpdate({children = null}) {
const didMountRef = useRef(false);
useEffect(() => {
if (didMountRef.current) {
console.warn('This warning fires on every update');
console.error('This error fires on every update');
} else {
didMountRef.current = true;
}
});
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorAndWarningOnUnmount({children = null}) {
useEffect(() => {
return () => {
console.warn('This warning fires on unmount');
console.error('This error fires on unmount');
};
}, []);
return children;
}
// $FlowFixMe[missing-local-annot]
function ReallyLongErrorMessageThatWillCauseTextToBeTruncated({
children = null,
}) {
console.error(
'This error is a really long error message that should cause the text to be truncated in DevTools',
);
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorWithMultipleArgs({children = null}) {
console.error('This error', 'passes console', 4, 'arguments');
return children;
}
// $FlowFixMe[missing-local-annot]
function ErrorWithStringSubstitutions({children = null}) {
console.error('This error uses "%s" substitutions', 'string');
return children;
}
// $FlowFixMe[missing-local-annot]
function ReactErrorOnHostComponent({children = null}) {
return <div data-camelCasedAttribute="should-lower-case">{children}</div>;
}
// $FlowFixMe[missing-local-annot]
function DuplicateWarningsAndErrors({children = null}) {
console.warn('this warning is logged twice per render');
console.warn('this warning is logged twice per render');
console.error('this error is logged twice per render');
console.error('this error is logged twice per render');
return <div data-camelCasedAttribute="should-lower-case">{children}</div>;
}
// $FlowFixMe[missing-local-annot]
function MultipleWarningsAndErrors({children = null}) {
console.warn('this is the first warning logged');
console.warn('this is the second warning logged');
console.error('this is the first error logged');
console.error('this is the second error logged');
return <div data-camelCasedAttribute="should-lower-case">{children}</div>;
}
// $FlowFixMe[missing-local-annot]
function ComponentWithMissingKey({children}) {
return [<div />];
}
function ComponentWithSymbolWarning() {
console.warn('this is a symbol', Symbol('foo'));
console.error('this is a symbol', Symbol.for('bar'));
return null;
}
export default function ErrorsAndWarnings(): React.Node {
const [count, setCount] = useState(0);
const handleClick = () => setCount(count + 1);
return (
<Fragment>
<h1>Inline warnings</h1>
<button onClick={handleClick}>Update {count > 0 ? count : ''}</button>
<ComponentWithMissingKey />
<WarnDuringRender />
<WarnOnMount />
<WarnOnUpdate />
{count === 0 ? <WarnOnUnmount /> : null}
{count === 0 ? <WarnOnMount /> : null}
<ErrorDuringRender />
<ErrorOnMount />
<ErrorOnUpdate />
{count === 0 ? <ErrorOnUnmount /> : null}
<ErrorAndWarningDuringRender />
<ErrorAndWarningOnMount />
<ErrorAndWarningOnUpdate />
{count === 0 ? <ErrorAndWarningOnUnmount /> : null}
<ErrorWithMultipleArgs />
<ErrorWithStringSubstitutions />
<ReactErrorOnHostComponent />
<ReallyLongErrorMessageThatWillCauseTextToBeTruncated />
<DuplicateWarningsAndErrors />
<MultipleWarningsAndErrors />
<ComponentWithSymbolWarning />
</Fragment>
);
}