Warning: Functions are not valid as a React child.This may happen if you return a Component instead of <Component /> from render - javascript

I get the above error when I try to display {props.child}.The page remains blank.The detailed warning is
index.js:1 Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
in div (at CustomLayout.js:28)
in main (created by Basic)
in Basic (created by Context.Consumer)
in Content (at CustomLayout.js:22)
in section (created by BasicLayout)
in BasicLayout (created by Context.Consumer)
in Layout (at CustomLayout.js:8)
in CustomLayout (at App.js:10)
in div (at App.js:9)
in App (at src/index.js:7)
Below are the project files. Article.js is a component and ArticleListView and CustomLayout are containers to it. I am trying to access the child elements in CustomLayout.js by {props.children}
App.js
import React from 'react';
import './App.css';
import 'antd/dist/antd.css';
import CustomLayout from './containers/CustomLayout'
import ArticleListView from './containers/ArticleListView';
function App() {
return (
<div className="App">
<CustomLayout>
{ArticleListView}
</CustomLayout>
</div>
);
}
export default App
ArticleListView.js
import React from 'react'
import Article from '../components/Article'
class ArticleListView extends React.Component{
render(){
return(
<Article/>
);
}
}
export default ArticleListView
Article.js
import React from 'react'
import { List, Avatar, Icon } from 'antd';
const listData = [];
for (let i = 0; i < 23; i++) {
listData.push({
href: 'http://ant.design',
title: `ant design part ${i}`,
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
description:
'Ant Design, a design language for background applications, is refined by Ant UED Team.',
content:
'We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.',
});
}
const IconText = ({ type, text }) => (
<span>
<Icon type={type} style={{ marginRight: 8 }} />
{text}
</span>
);
function Article(props){
return(
<List
itemLayout="vertical"
size="large"
pagination={{
onChange: page => {
console.log(page);
},
pageSize: 3,
}}
dataSource={listData}
footer={
<div>
<b>ant design</b> footer part
</div>
}
renderItem={item => (
<List.Item
key={item.title}
actions={[
<IconText type="star-o" text="156" key="list-vertical-star-o" />,
<IconText type="like-o" text="156" key="list-vertical-like-o" />,
<IconText type="message" text="2" key="list-vertical-message" />,
]}
extra={
<img
width={272}
alt="logo"
src="https://gw.alipayobjects.com/zos/rmsportal/mqaQswcyDLcXyDKnZfES.png"
/>
}
>
<List.Item.Meta
avatar={<Avatar src={item.avatar} />}
title={<a href={item.href}>{item.title}</a>}
description={item.description}
/>
{item.content}
</List.Item>
)}
/>
);
}
export default <Article/>
CustomLayout.js
import React from 'react'
import { Layout, Menu, Breadcrumb } from 'antd';
const { Header, Content, Footer } = Layout;
function CustomLayout(props){
return(
<Layout className="layout">
<Header>
<div className="logo" />
<Menu
theme="dark"
mode="horizontal"
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
>
<Menu.Item key="1">nav 1</Menu.Item>
<Menu.Item key="2">nav 2</Menu.Item>
<Menu.Item key="3">nav 3</Menu.Item>
</Menu>
</Header>
<Content style={{ padding: '0 50px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<div style={{ background: '#fff', padding: 24, minHeight: 280 }}>{props.children}</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
</Layout>
);
}
export default CustomLayout

If you are using any javascript expression then only use curly braces like - {a+b}.
but form html tags or react component you need to import as per react standard.
Use like this
<CustomLayout>
<ArticleListView />
</CustomLayout>
and change your export default <Article/> to export default Article

It should be <ArticleListView/>, not {ArticleListView}

Try
<CustomLayout>
<ArticleListView />
</CustomLayout>
rather than
<CustomLayout>
{ArticleListView}
</CustomLayout>

in javascript we work like isConditionTrue ? screenOne :screenTwo
but in typescript we have to change isConditionTrue ? :

Related

breakpoints not working in MUI v5 and react project

I'm trying to use breakpoints for responsive design in my page, but it dosent really seem to work. Whenever i apply any breakpoint, the whole page goes blank.
Here's my code:-
Styles.js
import { makeStyles } from "#mui/styles";
const useStyles = makeStyles((theme) => ({
title: {
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
}));
export default useStyles;
Header.jsx
import React from 'react';
import { Autocomplete } from '#react-google-maps/api';
import { AppBar, Toolbar, Typography, InputBase, Box } from '#mui/material';
import SearchIcon from '#mui/icons-material/Search';
import useStyles from './styles';
const Header = () => {
const classes = useStyles();
return (
<>
<AppBar position='static'>
<Toolbar className={classes.toolbar}>
<Typography variant='h5' className={classes.title}>
Travel Advisor
</Typography>
{/* Box acts as Div */}
<Box display='flex'>
<Typography variant='h6' className={classes.title}>
Explore new places
</Typography>
{/* <Autocomplete> */}
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase placeholder='Search...' classes={{ root: classes.inputRoot, input: classes.inputInput }} />
</div>
{/* </Autocomplete> */}
</Box>
</Toolbar>
</AppBar>
</>
)
}
export default Header;
Before applying breakpoints :-
Before breakpoint
After applying breakpoints :-
After breakpoint
Make sure that you created breakpoints correctly.
https://mui.com/material-ui/customization/breakpoints/
And check if you have wrapped your app in ThemeProvider.
And I want to note that #mui/styles is deprecated. Perhaps this problem may be related to this.
https://mui.com/system/styles/basics/
⚠️ #mui/styles is the legacy styling solution for MUI. It depends on JSS as a styling solution, which is not used in the #mui/material anymore, deprecated in v5. If you don't want to have both Emotion & JSS in your bundle, please refer to the #mui/system documentation which is the recommended alternative.
⚠️ #mui/styles is not compatible with React.StrictMode or React 18.
Dont use it on newly created app.

How to use React Router Link component inside an Ant Design Tab component

it's been since a week that I try to resolve a problem to use React Router Link component with Ant Design Tabs component.
First I basically followed the nested route section from React Router documentation to create a Switch component with route according to desired path.
As I will have to reuse the Tab component on other components later, I create a basic custom TabMenu component into which I pass an array with tab name to map dynamicaly the required tabs.
I tried to wrap a Link component inside the the TabPane component for each mapped value but it doesn't work.
I saw many solution trying to resolve the problem, especially by passing the Link inside the tab props of TabPane component or using the onChange Tab prop with history hook to push to desired location.
I tried both but these solutions seems a little tricky for me and don't really suit me.
The first only work if I click on the tab text because of the Link only affect the text inside tab and not the entire tab. The second work too but the use of history in this case does not seem 'conventional' to me.
I really hope there is a basic solution only with Link component. Here is my code. Thank you
import { Layout, Menu } from 'antd'
import { Link } from 'react-router-dom'
import { AimOutlined, BookOutlined, DashboardOutlined } from '#ant-design/icons'
const { SubMenu } = Menu
const { Sider } = Layout
const SideMenu = () => {
return (
<Sider width={208} style={{
marginTop: 64, overflow: 'auto',
zIndex: 1,
height: '100vh',
position: 'fixed',
left: 0
}}>
<Menu defaultSelectedKeys={['topMenuItem1']} defaultOpenKeys={['sub1']} className={'side-menu'} mode="inline">
<Menu.Item key={'topMenuItem1'} icon={<DashboardOutlined/>}>
<Link to={'/'}> Tableau de bord </Link>
</Menu.Item>
<Menu.Item key={'topMenuItem2'} icon={<BookOutlined/>}>
<Link to={'/missions-catalog'}>Catalogue de missions</Link>
</Menu.Item>
<SubMenu key="sub1" icon={<AimOutlined/>} title="Vos missions">
<Menu.Item key="1">
<Link to={'/company-referent-missions'}> Missions personnelles </Link>
</Menu.Item>
<Menu.Item key="2">
<Link to={'/company-referent-missions/documents'}>Documents</Link>
</Menu.Item>
<Menu.Item key="3">
<Link to={'/company-referent-missions/favoris'}>Favoris</Link>
</Menu.Item>
</SubMenu>
</Menu>
</Sider>
)
}
export default SideMenu
import { Layout, PageHeader } from 'antd'
import { Route, Switch } from 'react-router'
import DashboardEmployeesMissions from '../pages/Dashboard/DashboardEmployeesMissions'
import MyAccount from '../pages/MyAccount'
import CompanyReferentMissions from '../pages/CompanyReferentMissions'
import DashboardHome from '../pages/Dashboard/DashboardHome'
import BreadcrumbNavigation from './BreadcrumbNavigation'
import MissionsCatalogHome from '../pages/MissionsCatalog/MissionsCatalogHome'
const { Content } = Layout
const MainContent = () => {
return (
<Content style={{ marginTop: 64, marginLeft: 208, minHeight: '100vh' }} className="main-content">
<PageHeader title="Tableau de bord" breadcrumb={<BreadcrumbNavigation/>} subTitle="Accueil"/>
<div className={'main-container'} style={{ backgroundColor: '#F7FBFC', padding: '24px' }}>
<Switch>
<Route exact={true} path={'/'}>
<DashboardHome/>
</Route>
<Route path={'/missions-catalog'}>
<MissionsCatalogHome/>
</Route>
<Route path={'/company-referent-missions'}>
<CompanyReferentMissions/>
</Route>
<Route path={'/employees-missions'}>
<DashboardEmployeesMissions/>
</Route>
<Route path={'/my-account'}>
<MyAccount/>
</Route>
</Switch>
</div>
</Content>
)
}
export default MainContent
import React from 'react'
import MissionListItem from '../components/MissionsListItem'
import { Space } from 'antd'
import Title from 'antd/es/typography/Title'
import { Route, Switch, useRouteMatch } from 'react-router-dom'
import MissionCatalogList from './MissionsCatalog/MissionCatalogList'
import { missionApplicationData, missionCatalogData } from '../helpers/DataSeed'
import TabMenu from '../components/TabMenu'
const referentMissionsTabsName = ['Missions', 'Documents', 'Favoris']
const CompanyReferentMissions = () => {
let { url, path } = useRouteMatch()
return (
<Space direction={'vertical'} style={{ width: '100%' }}>
<Space direction={'vertical'}>
<Title level={4}>Mission personnelles</Title>
<TabMenu tabName={referentMissionsTabsName} tabRouterUrl={url}/>
</Space>
<Switch>
<Route exact={true} path={`${path}`}>
<Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
<MissionListItem headerListTitle={<Title level={3}>Candidatures</Title>}
dataSource={missionApplicationData()}/>
<MissionListItem headerListTitle={<Title level={3}>Missions acceptées</Title>}/>
<MissionListItem headerListTitle={<Title level={3}>Missions terminées</Title>}/>
</Space>
</Route>
<Route path={`${path}/documents`}>
<Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
<MissionListItem headerListTitle={<Title level={3}>Lettres de missions</Title>}/>
<MissionListItem headerListTitle={<Title level={3}>Attestations de temps passé</Title>}/>
<MissionListItem headerListTitle={<Title level={3}>Ressources</Title>}/>
</Space>
</Route>
<Route path={`${path}/favoris`}>
<Space direction={'vertical'} size={'large'} style={{ width: '100%' }}>
<MissionCatalogList missionsCatalogData={missionCatalogData}/>
</Space>
</Route>
</Switch>
</Space>
)
}
export default CompanyReferentMissions
import { Tabs } from 'antd'
import React from 'react'
const { TabPane } = Tabs
const TabMenu = ({ tabName }) => {
return (
<Tabs defaultActiveKey={1}>
{tabName.map((name, index) => {
return (
<TabPane key={index + 1} tab={name}/>
)
})}
</Tabs>
)
}
export default TabMenu
If you want to show the active tab depending on the location, you can do something like this
import { Tabs } from 'antd'
import React from 'react'
import { useLocation } from 'react-router-dom';
const { TabPane } = Tabs
const TabMenu = ({ tabName }) => {
const location = useLocation();
return (
<Tabs
defaultActiveKey={1}
activeKey={tabName.find((name) => name === location.pathname)}
>
{tabName.map((name, index) => {
return (
<TabPane key={index + 1} tab={name}/>
)
})}
</Tabs>
)
}
export default TabMenu
If you wanted to do something different, please describe in more detail and provide a link to the https://codesandbox.io with a minimal example

How to call a function to main App file? React Native

I have just started learning React Native. I am trying to insert bottom menu tabs on my first app.
I am using this code on Tabs.js (this is just the export part):
export default function Tabs() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
Unfortunately, I don't know how to call it to my main App file (this is just one of my attempts):
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
Tabs();
I've read about exporting default function, but I don't understand how to use it in my main App file. I'm sure that this is a syntax issue.
Also, I am planning to add a background colour to all tabs. Any advice?
Thank you.
UPDATE:
This is my Tabs file.
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '#expo/vector-icons';
const Tabs = () => {
function Feed() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
function Profile() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
function MainPage() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text></Text>
</View>
);
}
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
tabBarOptions={{
activeTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="MainPage"
component={MainPage}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="pill" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: '',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="format-list-text" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
export default Tabs
This is my main App file.
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
const App=()=>{
return <Tabs />
}
Make sure to export the App as default. You most probably have a file called index.js in the root folder and that is importing your App component.
Your App.js file should look like this:
import * as React from 'react';
import { Text, View } from 'react-native';
import Tabs from './Tabs.js';
export default const App=()=>{
return <Tabs />
}
And then your index.js file looks like this:
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
You don't necessarily have to export as default, because you can only have one default export. If you export App as default you import it like this: import App from './App'; and if you export without a default, you have to import like this: import {App} from './App'
And to get an advice how to add background color to the tabs, check here: How to set the background color of Tab.Navigator?
you basically call it like would call a component
btw your Tabs should export like this
const Tabs=()=>{
/...
}
export default Tabs
const App=()=>{
return <Tabs />
}

How to map data into cards react.js

I'm trying to build a simple shop in react.js.
My next step would be mapping the products which I store in data.js file into separate cards and then a product list. I am using external libraries for Card.
This is data.js (example):
export const data = [
{
id: 1,
title: "example title",
content: "example content",
image: "https://i.imgur.com/example.jpg"
},
{
id: 2,
title: "example title",
content: "example content",
image: "https://i.imgur.com/example.jpg"
},
{
id: 3,
title: "example title",
content: "example content",
image: "https://i.imgur.com/example.jpg"
},
]
That would be a component rendering a single product card:
import React from 'react';
import { Button } from 'react-bootstrap'
import { Card } from '#material-ui/core';
import Col from 'react-bootstrap/Col';
import { data } from '../../../data'
const Product = () => (
<Col xs={12} md={6} lg={4} key={data.id}>
<Card style={{ width: '18rem' }}>
<Card.Header></Card.Header>
<Card.Img variant="top" src={data.image} />
<Card.Body>
<Card.Title>{data.title}</Card.Title>
<Card.Text>
{data.content}
</Card.Text>
<Button variant="primary">Add to cart</Button>
<Button>Add to favs</Button>
</Card.Body>
</Card>
</Col>
)
export default Product;
and finally, the component rendring many products:
import React from 'react';
import Row from 'react-bootstrap/Row';
import {data} from '../../../data'
import Product from '../Product/Product';
import styles from './Shop.module.scss';
const Shop = () => {
return (
<div className='row-wrapper'>
<Row>
{data.map(product => (
<Product key={product.id} {...product} />
))}
</Row>
</div>
)
};
export default Shop;
This does not work, I receive errors in the console. What am I missing?
edit: the error I get:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
stacktrace:
Blockquote
Check your code at Product.js:13.
in Product (at Shop.js:17)
in div (created by Row)
in Row (at Shop.js:15)
in div (at Shop.js:14)
in Shop (created by Context.Consumer)
in Route (at Header.js:24)
in Switch (at Header.js:22)
in div (at Header.js:13)
in Header (at MainLayout.js:15)
in div (at MainLayout.js:13)
in MainLayout (at App.js:12)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:11)
in App (at src/index.js:6)
You can pass the product details from the shop component to the Product Component through the props, the following code should works:
Product Component
import React from 'react';
import { Button } from 'react-bootstrap'
import { Card } from '#material-ui/core';
import Col from 'react-bootstrap/Col';
const Product = ({product}) => (
<Col xs={12} md={6} lg={4} key={product.id}>
<Card style={{ width: '18rem' }}>
<Card.Header></Card.Header>
<Card.Img variant="top" src={product.image} />
<Card.Body>
<Card.Title>{product.title}</Card.Title>
<Card.Text>
{product.content}
</Card.Text>
<Button variant="primary">Add to cart</Button>
<Button>Add to favs</Button>
</Card.Body>
</Card>
</Col>
)
export default Product;
Shop Component
import React from 'react';
import Row from 'react-bootstrap/Row';
import {data} from '../../../data'
import Product from '../Product/Product';
import styles from './Shop.module.scss';
const Shop = () => {
return (
<div className='row-wrapper'>
<Row>
{data.map(product => (
<Product key={product.id} product={product} />
))}
</Row>
</div>
)
};
export default Shop;

How to set the style a react.js component when creating it?

How to set the style a react.js component when creating it?
Below is some of my code (partially inherited from a stronger developer and then simplified for brevity).
I want to re-use my LogComponent to print several pages of a Log. However, in some cases I want to force a particular width on the returned List, rather than allowing it to flex as it sees fit.
I would prefer to not define a separate LogComponentFixed or to have an if (...) {return (...)} else {return(...)} in my LogComponent.
I have in mind to do something in Log.js like:
<LogComponent heading={"Page 1"}, lines={page_1}, style={styles.list_1} />
<LogComponent heading={"Page 1"}, lines={page_1}, style={styles.list_2} />
And to then, in LogComponent do something like:
<List style={style}> ... </List>
I also tried using something like
<List className={list_1}> ... </List>
But none of the things I've tried works...
Log.js
import React from 'react'
import Typography from '#material-ui/core/Typography'
import { withStyles } from '#material-ui/core/styles'
import LogComponent from './LogComponent'
const styles = theme => ({
title: {
padding: theme.spacing.unit*1.5,
},
list_1: {
},
list_2: {
width: "300px"
},
listContainer: {
flexGrow: 1,
minHeight: 0,
overflow: 'auto'
},
})
const Log = ({classes, log}) => {
const page_1 = log[0];
const page_2 = log[1];
return (
<div>
<Typography className={classes.title} color="textSecondary" key={1}>
Example Log
</Typography>
<div className={classes.listContainer} key={2}>
<LogComponent heading={'Page 1'} lines={page_1} />
<LogComponent heading={'Page 2'} lines={page_2} />
</div>
</div>
export default withStyles(styles)(Log)
LogComponent.js
import React from 'react'
import Typography from '#material-ui/core/Typography'
import { withStyles } from '#material-ui/core/styles'
import { List, ListItem, ListItemText } from '#material-ui/core';
const styles = theme => ({
title: {
padding: theme.spacing.unit*1.5,
},
}
const LogComponent = ({classes, list_class, heading, lines}) => {
return (
<div className={classes.root}>
<Typography className={classes.title} color="textSecondary" key={1}>
{heading}
</Typography>
<div>
<List dense>
{[...lines[0]].map(e =>
<ListItem><ListItemText primary={e} /></ListItem>
)}
</List>
</div>
</div>
)
}
export default withStyles(styles)(LogComponent)
Here you are sending the styles as a prop to LogComponent, that's why it will not be applied as styles to that component you have created. The style attribute is for HTML tags and in material-ui, you can pass styles to a wrapper component also.
In your case you can get the styles inside your LogComponent as below:
Send styles as a prop as you mentioned in the question
<LogComponent heading={"Page 1"}, lines={page_1}, style={styles.list_1} />
Now, you can access it from props,
// right below get the style
const LogComponent = ({classes, list_class, heading, lines, style}) => {
return (
<div className={classes.root} style={style}> // Look style attribute added, style(value) is from props
<Typography className={classes.title} color="textSecondary" key={1}>
{heading}
</Typography>
<div>
<List dense>
{[...lines[0]].map(e =>
<ListItem><ListItemText primary={e} /></ListItem>
)}
</List>
</div>
</div>
)
}

Categories