"Functions are not valid as a React child" error message shows up after adding JavaScript Map function - array.prototype.map

I added a normal array.prototype.map function to iterate through an array in my code, but keep getting a warning error. I double checked the syntax for the map function and that does not seem to be the issue. I have also tried passing different arrays into the function with different values.
Here is the warning error.
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
And my code:
function App() {
const[items, setItems] =
useState([{toDo: 'vacuum', done: false},
{toDo: 'Do laundry', done: false},
{toDo: 'Walk the dog', done: false}])
return (
<div>
{
(items.map = (item, index) => {
<p>{item}</p>;
})
}
</div>
);
};
This is the error path in the console:
at div
at Home
at Route (http://localhost:3000/static/js/bundle.js:41724:29)
at Switch (http://localhost:3000/static/js/bundle.js:41926:29)
at div
at div
at Router (http://localhost:3000/static/js/bundle.js:41355:30)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:39344:35)
at App
at Router (http://localhost:3000/static/js/bundle.js:41355:30)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:39344:35)
I am wondering if it is at all related to my index.js page.
This is what it currently looks like.
import React from "react";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import reactDom from "react-dom/client";
const root = reactDom.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
Any help would be much appreciated!

Related

How to use hooks in custom plugins

I am trying to write a custom plugin for our Docusaurus site. I am able to wire up the custom component, but I cannot use hooks like useState or useEffect. The page crashes saying I'm using an invalid React hook.
I know its possible to use hooks because I see other plugins doing it so I'm sure its a syntax problem somewhere.
Here's my code:
index.ts
import path from 'path'
module.exports = function () {
return {
name: 'docusaurus-theme-myorg-technology',
getThemePath() {
return path.resolve(__dirname, './theme')
}
};
};
theme/index.tsx
import React from 'react'
import {CustomTOC} from './CustomTOC'
const WrappedTOC = (props: any) => {
return (
<CustomTOC {...props} />
);
};
export default WrappedTOC;
theme/CustomTOC.tsx
import React, { useState } from 'react';
import TOC from '#theme-init/TOC';
export default function CustomTOC(props: any) {
//const [tags, setTags] = useState<any[]>([]); <-- if I comment this out the page crashes
return (
<>
<TOC {...props} />
Hello world
</>
);
}
"Invalid hooks call" link to a doc page, that you should read carefully.
Most likely: you are using a different version of React for your component lib that the one Docusaurus uses internally, and it leads to the React lib being used twice at runtime. Make sure the final project will only include one React version. You can for example use the exact same version that the one Docusaurus uses

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) in react native project

I am building a react native project I get the following error:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of SignInScreen.
Here is my code.
import React from 'react';
import { View,Image,StyleSheet,useWindowDimensions } from 'react-native';
import Logo from'../../../assetss/images/logo.png';
import CustomInput from '../../components/CustomInput';
const SignInScreen = () => {
const {height} = useWindowDimensions();
return (
<View style= {styles.root}>
<Image source={Logo} style ={[styles.logo, {height: height * 0.3}]}
resizeMode="contain" />
<CustomInput />
</View>
);
};
const styles = StyleSheet.create({
root: {
alignItems: 'center',
padding: 20,
},
logo:{
width: 1000,
maxWidth: 1100,
maxHeight: 200 ,
}
})
export default SignInScreen
There is a difference between named exports and default exports.
Named Export
Can be used for top level values of a module, e.g.
export const fetch = () => {
}
export const Component = () => {
return <></>
}
The above can be imported using
import { fetch, Component } from "./MyModule"
Notice the curly braces.
Default Export
A default export can only be used once per file, e.g.
const Component = () => {
return <></>
}
export default Component;
The above can be imported using
import Component from "./MyModule"
Notice that we have not used curly braces here.
The error message
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
tells us that we have mixed this up for some of our imports. Your imports for View, Image, StyleSheet and useWindowDimensions are correct. Hence, either CustomInput or Logo is not correctly imported (or exported; it depends on how we want to see it).
You are assuming default exports for both. Check if they are exported using default export.
If you do not want to use default exports, then you need to change your import statements to the following.
import { CustomInput } from '../../components/CustomInput';
Furthermore, check that the import paths, e.g. '../../../assetss/images/logo.png' and '../../components/CustomInput', are correct.
In my case the problem was I created all components but didn't save the files. I don't use autosave, so I created all components, imported them to my Home component, but they were not saved so that error was thrown. Once I saved each file, the error disappeared.
Sounds like you had an index.js file in your CustomInput folder, so when you wrote
import CustomInput from './../../components/CustomInput';
it thought you wanted
import {CustomInput} from './../../components/CustomInput/index.js';
but really you wanted
import CustomInput from './../../components/CustomInput/CustomInput.js';
This error
"Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of ..."
shows up for many different types of errors that directly or indirectly eventually boil down to export/import default/named. Besides your case where it thought you were looking in index.js for a {named} in curly braces export/import, you can also get that error message if you accidentally misspell your named import, for example: import {Flatlist} with a lowercase l instead of import {FlatList} with an uppercase L.
thanks for your help my probl/em is solved b/y just putting .js . For example import CustomInput from './../../components/CustomInput/CustomInput.js
From the code you have shown, it seems like assets is spelt wrong. You can check if the actual folder is spelt like that.
Faced while unit test in react
Notices the same issue while writing unit test case using jest and react-testing-library.
Problem: It may be due to wrong way of mocking the component using jest.mock
Problem Situation:
jest.mock('./components/notes-list', () => {
return {
NotesList: () => <div data-testid='note-list-component'>Hello World</div>,
};
});
Solution
jest.mock('./components/notes-list', () => {
const NotesList = () => (
<div data-testid='note-list-component'>Hello World</div>
);
return NotesList;
});
This error message is indicating that there is an issue with a component in your React application. Specifically, React is expecting the component to be either a string (for built-in components such as div or span) or a class or function (for custom components defined by you). However, in this case, the component is undefined.
There are a few potential causes for this error:
Forgetting to export the component: If the component is defined in a separate file, make sure that it is properly exported at the end of the file. For example:
// MyComponent.js
import React from 'react';
class MyComponent extends React.Component {
render() {
return <div>Hello, World!</div>;
}
}
export default MyComponent;
Mixing up default and named imports: If you are importing the component into another file, make sure that you are using the correct syntax. For example:
// App.js
import React from 'react';
import MyComponent from './MyComponent';
function App() {
return <MyComponent />;
}
export default App;
If you're still encountering the error after checking these potential causes, it may be helpful to look at the surrounding code to see if there is anything else that could be causing the issue. Additionally, make sure that the version of React that you are using is compatible with the version of react-dom that you have installed.

Is is possible to use a custom notification library in react-admin instead of the built-in notifications? [duplicate]

How could i make react-admin to show a multi-line notification / error message on the snackbar?
Having the following dataProvider:
export default (type, resource, params) => {
throw new Error(`
Message line 1.
Message line 2.
Message line 3.
`);
};
That shows a single line message when loading a List component:
error notification screenshot
UPDATE 2022:
Since version 4 of react-admin, you can tell the useNotify hook, to use a multi line message passing the multiLine prop: https://marmelab.com/react-admin/useNotify.html#:~:text=multiLine%3A%20Set%20it%20to%20true%20if%20the%20notification%20message%20should%20be%20shown%20in%20more%20than%20one%20line.
End of UPDATE.
Ok, with the help of the docs I manage to do what I wanted.
Defining a custom Layout component to be used by the App component and passing it a custom Notification component.
// ./MyLayout.js
import React from 'react';
import { Layout } from 'react-admin';
import MyNotification from "../MyNotification";
const CustomLayout = props => (
<Layout {...props} notification={MyNotification} />
);
export default CustomLayout;
Then I pass a custom CSS class to the Notification component.
// ./MyNotification.js
import React from 'react';
import {withStyles} from '#material-ui/core/styles';
import {Notification} from 'react-admin';
// Allow multi-line messages to be displayed
const cssMsg = {
snackbarContent: {
whiteSpace: 'pre-wrap'
}
};
const MyNotification = withStyles(cssMsg)(({classes, ...props}) => (
<Notification {...props} className={classes.snackbarContent}/>
));
export default MyNotification;
error notification screenshot multi-line

React-admin: Multi-line notification messages

How could i make react-admin to show a multi-line notification / error message on the snackbar?
Having the following dataProvider:
export default (type, resource, params) => {
throw new Error(`
Message line 1.
Message line 2.
Message line 3.
`);
};
That shows a single line message when loading a List component:
error notification screenshot
UPDATE 2022:
Since version 4 of react-admin, you can tell the useNotify hook, to use a multi line message passing the multiLine prop: https://marmelab.com/react-admin/useNotify.html#:~:text=multiLine%3A%20Set%20it%20to%20true%20if%20the%20notification%20message%20should%20be%20shown%20in%20more%20than%20one%20line.
End of UPDATE.
Ok, with the help of the docs I manage to do what I wanted.
Defining a custom Layout component to be used by the App component and passing it a custom Notification component.
// ./MyLayout.js
import React from 'react';
import { Layout } from 'react-admin';
import MyNotification from "../MyNotification";
const CustomLayout = props => (
<Layout {...props} notification={MyNotification} />
);
export default CustomLayout;
Then I pass a custom CSS class to the Notification component.
// ./MyNotification.js
import React from 'react';
import {withStyles} from '#material-ui/core/styles';
import {Notification} from 'react-admin';
// Allow multi-line messages to be displayed
const cssMsg = {
snackbarContent: {
whiteSpace: 'pre-wrap'
}
};
const MyNotification = withStyles(cssMsg)(({classes, ...props}) => (
<Notification {...props} className={classes.snackbarContent}/>
));
export default MyNotification;
error notification screenshot multi-line

How to not put "use strict" everywhere

I'm trying to write some tests for a React app I've been working on, and I figured I would use Jest since it's mentioned in the React docs.
I'm using Webpack and so far I've installed jest-cli, babel-jest, and I included the following configuration in package.json:
"jest": {
"scriptPreprocessor": "./node_modules/babel-jest",
"unmockedModulePathPatterns": [
"./node_modules/react",
"./node_modules/react-dom"
],
}
So, I'm writing the tests for some file foo.js. This file includes some other module bar.js (i.e. const bar = require('./bar');). Unfortunately, when I run jest I get the following error:
SyntaxError: Block-scoped declarations (let, const, function, class) not yet
supported outside strict mode in file 'js/foo.js'.
So, after some research, I find out I have to include 'use strict'; at the top of foo-test.js. However, for some reason, I still get the same error unless I also include 'use strict'; at the top of foo.js.
So my question is: am I doing something wrong? If not, is there anyway for me to write my tests using Jest without having to write 'use strict'; at the top of all my source files?
It seems to test out basic ES2015 classes with jest, use strict is required, however to test React Components, 'use strict' isn't required. Here's an example
//CheckboxWithLabel.js
import React, {Component} from 'react';
class CheckboxWithLabel extends Component {
constructor(){
super(...arguments);
this.state = {
isChecked: false
};
this.onChange = this.onChange.bind(this);
}
onChange() {
this.setState({
isChecked: !this.state.isChecked
});
}
render() {
return (
<label>
<input type="checkbox"
checked={this.state.isChecked}
onChange={this.onChange} />
{this.state.isChecked ? this.props.labelOn : this.props.labelOff }
</label>
);
}
}
export default CheckboxWithLabel;
//CheckboxWithLabel_tests.js
jest.disableAutomock(); //use this instead of jest.autoMockOff()
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import CheckboxWithLabel from '../source/components/CheckboxWithlabel';
// const CheckboxWithLabel = require('../source/components/CheckboxWithLabel');
describe('CheckboxWithlabel', () => {
const shallowRenderer = TestUtils.createRenderer();
//render a checkbox
const checkbox = TestUtils.renderIntoDocument(
<CheckboxWithLabel labelOn="On" labelOff="Off" />
);
// shallowRenderer.render(<CheckboxWithLabel labelOn="On" labelOff="Off" />)
// const checkbox = shallowRenderer.getRenderOutput();
// it('defaults to unchecked and off label', () => {
// const inputField = checkbox.props.children[0];
// const textNode = checkbox.props.children[1];
// expect(inputField.props.checked).toBe(false);
// expect(textNode).toEqual('Off');
// })
var checkboxNode = ReactDOM.findDOMNode(checkbox);
// let checkboxElement = TestUtils.findRenderedDOMComponentWithTag(checkbox, 'input');
it('defaults to Off label', () => {
expect(checkboxNode.textContent).toEqual('Off');
// expect(checkboxElement.checked).toBe(false);
});
})
Edited: This is not required anymore
Notice the only caveat being that you have to explicitly add a auto_mock_off.js file that simply adds this line (it took me hours to figure this one out)
jest.autoMockOff();
More information can be found on this thread on github Github React Issue #932
That's it! the component testing works perfectly. I've also tried the same example with shallow rendering and it worked perfectly too! Hope this helps!