Invalid prop `children` supplied to `DropdownItem` expected a ReactNode - reactjs

components: DropdownItem
reactstrap version ^8.0.0
react version ^16.8.6
bootstrap version ^4.3.1
I am using reactstrap dropdown. And I am trying to populate the dropdown items using a map function
render() {
return (
<Dropdown isOpen={this.state.open} toggle={this.toggle}>
<DropdownToggle caret>
{this.props.name}
</DropdownToggle>
<DropdownMenu>
{this.props.items.map(function(item) {
return(
<DropdownItem key={item}>
<text>{item}</text>
</DropdownItem>
);
})}
</DropdownMenu>
</Dropdown>
);
}
If I do not wrap the {item} inside a tag(div or text) I get the following error while running test case.
console.error node_modules/prop-types/checkPropTypes.js:20
Warning: Failed prop type: Invalid prop children supplied to DropdownItem, expected a ReactNode.
in DropdownItem
Just curious to know why am I getting the warning if I do not wrap it in a tag?

You are getting the warning because the DropdownItem is expecting a node as a child, and is not able to infer if your item is a valid react node or not, then throws the warning.
You could try wrapping the item in a <React.Fragment>, but I'm afraid it will not work, according to documentation on propTypes:
// Anything that can be rendered: numbers, strings, elements or an array // (or fragment) containing these types. optionalNode: PropTypes.node,
The good news are that propTypes checking only happens in development mode, once you transpile your app all warnings related to propTypes are gone, if you don't want to add the extra element and can live with the warning everything should be good.

I was getting this error, with a similar code, and it turned out to be that the value of item was an object and not a node or text.

Related

Warning: FindNodeDom is deprecated in Strictmode when using Collapse (from react-bootstrap)

I am having an issue with this code in my React project. It would show a div with a warning about filenames to upload.
<Collapse in={this.state.open} id={"z-hover"}>
<div>
<ul>
{ FilesAllowed.files.map((fileName, index) => {
return <li key={index}>{fileName}</li>
})}
</ul>
</div>
</Collapse>
I use a button to display the Collapse element (from react-bootstrap), but when the Collapse gets displayed, console returns this error (I can confirm it comes exactly from the Collapse element):
findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node
Edit: I put my functional code over here in codesandbox.
how could we do to avoid this warning? Thank you for reading:)

React Material UI Tooltips Disable Animation

I'm using React Material UI's Tooltip Component in my React application.
import Tooltip from "#material-ui/core/Tooltip";
...
...
<Tooltip title="Add" arrow>
<Button>Arrow</Button>
</Tooltip>
...
...
I want to disable the entry and exit animations. How can I achieve this in the latest version
You can use the TransitionComponent and the TransitionProps to solve this.
Use the Fade Transition component with timeout: 0 as the properties for the transition component:
import Tooltip from "#material-ui/core/Tooltip";
import Fade from "#material-ui/core/Fade";
...
<Tooltip
title="Add"
arrow
TransitionComponent={Fade}
TransitionProps={{ timeout: 0 }}
>
<Button>Arrow</Button>
</Tooltip>
Just disable/mock the transition component.
ie: render automatically the children like this:
const FakeTransitionComponent = ({ children }) => children;
<Tooltip
title="tooltip title"
TransitionComponent={FakeTransitionComponent}
// or TransitionComponent={({ children}) => children}
>
<h1>Hello CodeSandbox</h1>
</Tooltip>
Here is a codesandbox demo
I've used Incepter's solution, that is clean. If anyone is looking for a TypeScript solution here it is.
const FakeTransitionComponent = React.forwardRef<
HTMLDivElement,
TransitionProps & { children?: React.ReactElement<any, any> }
>(
(
{
appear,
onEnter,
onEntered,
onEntering,
onExit,
onExited,
onExiting,
...props
},
ref
) => {
props.in = undefined;
return <div {...props} ref={ref}></div>;
}
);
TransitionProps are not passed to the wrapper element, because they would all cause React warnings.
You can just pass React.Fragment as TransitionComponent
<Tooltip
title="tooltip title"
TransitionComponent={React.Fragment}
>
<h1>Hello CodeSandbox</h1>
</Tooltip>
Best option is to create a simple NoTransition component:
export const NoTransition = React.forwardRef<
React.ReactFragment,
TransitionProps
// eslint-disable-next-line #typescript-eslint/no-unused-vars
>(({ children }, ref) => {
return <>{ children }</>;
});
And do TransitionComponent={ NoTransition }.
Also, do not omit the ref param or you will get a warning too:
Warning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
Just adding TransitionProps={{ timeout: 0 }}, without setting TransitionComponent, will also work, but there's no need to render the default TransitionComponent in that case.
Some of the options proposed in other answers will throw errors or warnings:
Doing TransitionComponent={ Fragment } will result in the following warning:
Warning: Invalid prop appear supplied to React.Fragment. React.Fragment can only have key and children props.
Doing TransitionComponent={ ({ children }) => children } will result in this other warnings (might change a bit depending if you are using a Tooltip, Modal or other component):
Warning: Failed prop type: Invalid prop children supplied to ForwardRef(Modal). Expected an element that can hold a ref. Did you accidentally use a plain function component for an element instead? For more information see https://mui.com/r/caveat-with-refs-guide
Warning: Failed prop type: Invalid prop children supplied to ForwardRef(ModalUnstyled). Expected an element that can hold a ref. Did you accidentally use a plain function component for an element instead? For more information see https://mui.com/r/caveat-with-refs-guide
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? Check the render method of Unstable_TrapFocus.
And potentially also this error:
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
I'm using "#mui/material": "^5.5.2".

How to use MenuItem as a NavLink?

I am trying to use a menu list to navigate through my application. Although, the app and routes are working fine i get some warnings in console using this piece of code :
{props.itemList.map((item, index) =>(
<div key={index}>
<MenuItem component={NavLink} to={item.to} onClick=
{handleClose} activeClassName={classes.topNavLinkActive}
className={classes.topNavLink}>
{item.name}
<Icon className={classes.navIcon}>{item.icon}</Icon>
</MenuItem>
</div>
))}
The warnings I get are :
Warning: Failed prop type: Invalid prop component supplied to ForwardRef(ButtonBase). Expected an element type that can hold a ref. Did you accidentally provide a plain function component instead?
index.js:1375 Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
Can someone please explain why forward referencing is required here?
It seems like the error is about misusing the component property. The docs say:
The component used for the root node. Either a string to use a DOM element or a component.
According to MenuItem API, component property is of type elementType. The type definition file would show it's implementing JSX.IntrinsicElements interface (Which describe standard HTML tags).
NavLink element is a React component. Try providing a standard html tag name (string) or an actucal DOM node referance instead.

Unknown props warning when passing props to children

I'm trying to create a reusable dropdown menu wrapper component using this pattern:
class DropdownMenu extends React.Component {
render() {
return (
<span>
{React.cloneElement(
this.props.children,
{
menuOpen: this.props.menuOpen,
toggleMenu: this.props.toggleMenu
}
)}
</span>
);
}
}
const HeaderUserDropdown = ({menuOpen, toggleMenu }) => (
<DropdownMenu>
<div className={menuOpen ? 'visible' : ''}>
<button onClick={toggleMenu} />
</div>
</DropdownMenu>
)
But I get an error along the lines of Warning: Unknown props menuOpen, toggleMenu on <div> tag. Remove these props from the element. I know that I can use data- to get this working correctly, but that seems sort of hacky. What's the correct way to pass these props down to the children?
React distinguishes between HTML elements which are written in lower case (e.g. <div>) and React components which start with a capital letter.
In your code, you're trying to clone an HTML div element and add the properties menuOpen and toggleMenu, but these attributes are not supported by <div>, hence the warning. You need to set custom attributes on an HTML element, you'll need to use the data- prefix convention.

Having trouble getting ReactBootstrap contained modal to work

Here's the github link to my code https://github.com/jtylerm/Section9Lecture36
I am following along with a course from Udemy, we're writing a Pokedex site.
Warning: Failed prop type: Invalid prop `container` supplied to `Modal`.
in Modal (at PokemonModal.js:15)
in PokemonModal (at App.js:91)
in div (at App.js:70)
in App (at index.js:10)
I don't understand how 'container' is an invalid prop since that code was copied directly from the ReactBootstrap website https://react-bootstrap.github.io/components.html
Please help. Thanks!
***** UPDATE *****
Turns out you can either delete the prop 'container' entirely OR change the component from stateless to stateful, as Manolo suggests below. Hope this helps anyone with a similar error as what I had above.
You are using this inside a functional react component. In this context this === window. You should define your PokemonModal extending React.Component or React.PureComponent.
const PokemonModal = ({toggleModal, showModal, pokemon}) => {
return(
<div>
{/* ... */}
<Modal
show={showModal}
onHide={toggleModal}
container={this}
aria-labelledby="contained-modal-title"
>
{/* ... */}
</Modal>
</div>
)
}

Resources