Objects are not valid as a React child (found: [object HTMLDivElement]) - javascript

I want to pass a value to a div with id good in my index.html but it brings this error, Objects are not valid as a React child (found: [object HTMLDivElement]). If you meant to render a collection of children, use an array instead. in TestComponent (at App.js:49)
in div (at App.js:28)
in Apps (at index.js:7)
Please what am I doing wrong
TestComponent.js
import React, { Component } from 'react';
class TestComponent extends Component {
componentDidMount(){
console.log("Great");
}
render() {
// var {test} = this.props;
return (
<p>
{this.props.test}
</p>,
document.getElementById("good")
);
}
}
export default TestComponent;
App.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import TestComponent from "./components/TestComponent"
class Apps extends Component {
constructor(props){
super(props);
}
render() {
return (
<div>
<TestComponent test='doyin'/>
</div>
);
}
}
export default Apps;
Index.html
<div id="good"></div>

A class Component render function shouldn't use document.getElementById, you need to use ReactDOM.render to do that
import React, { Component } from 'react';
class TestComponent extends Component {
componentDidMount(){
console.log("Great");
}
render() {
// var {test} = this.props;
return (
<p>
{this.props.test}
</p>
);
}
}
export default TestComponent;
App
class Apps extends Component {
constructor(props){
super(props);
}
render() {
return (
<div>
<TestComponent test='doyin'/>
</div>
);
}
}
ReactDOM.render(<Apps />, document.getElementById("good"))
export default Apps;

In TestComponent.js, inside render function you are trying to return two elements, <p> and document.getElementById("good"). Probably you just wanted to return <p>:
render() {
return <p>{this.props.test}</p>;
}
Also, it looks like you've mistaken React.Component.render with ReactDOM.render(element, container[, callback]) where the second argument of the functions is the container.

Related

why my HOC Component is working properly ? #React

2 components :- ClickCounter, mouseHoverCounter !
1 HOC component to do the counting work.
earlier I was counting the click and mouse hover by writing separate counter method in each component(cliccounter,mousehovecounter),
but
now, I'm trying to pass the component into hoc counter & get the new component with only one change , where I'm passing a props to originalComponent and returning it to see the behavior but its now working...
import React, { Component } from 'react'
import updatedComponent from './hocCounter'
class ClickCounter extends Component {
constructor(props) {
super(props)
this.state = {
counter:0
}
}
ClickCounterHandler = () =>{
this.setState((prevState)=>{
return {counter:prevState.counter+1}
})
}
render() {
const count=this.state.counter
return (
<div>
<button onClick={this.ClickCounterHandler}>{this.props.name} Clicked {count} Times</button>
</div>
)
}
}
export default updatedComponent(ClickCounter)
import React, { Component } from 'react'
import updatedComponent from './hocCounter'
class HoverMouseCounter extends Component {
constructor(props) {
super(props)
this.state = {
counter:0
}
}
MouseOverCounter(){
this.setState((prevState)=>{
return {counter:prevState.counter+1}
})
}
render() {
const count=this.state.counter
return (
<div>
<h1 onMouseOver={this.MouseOverCounter.bind(this)}>{this.props.name} Hovered For {count} Time(s)</h1>
</div>
)
}
}
export default updatedComponent(HoverMouseCounter)
import React from 'react'
const updatedComponent = originalComponent => {
class newComponent extends React.Component {
render(){
return <originalComponent name='Harsh'/>
}
}
return newComponent
}
export default updatedComponent
In App.js, I'm returning
<ClickCounter></ClickCounter>
<HoverMouseCounter></HoverMouseCounter>
this only !
Check the error in the console,
index.js:1 Warning: <originalComponent /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements. at originalComponent
This means You are using the small letter in originalComponent
React components are expected to start with a capital letter
Try this in you HOC component
import React from 'react'
const updatedComponent = OriginalComponent => {
class NewComponent extends React.Component {
render(){
return <OriginalComponent name='Harsh'/>
}
}
return NewComponent
}
export default updatedComponent

How to import a component to UI?

Sorry, I am new in React.js, just switched from Java and I can't understand how I shall show my map on UI. Just give me a hint
import React from "react";
import {Map, GoogleApiWrapper} from 'google-maps-react';
class TestMap extends Component {
render() {
return (
<div className="GoogleMap">
<Map google={this.props.google} zoom={14} />
</div>
);
}
}
GoogleApiWrapper({
apiKey: ({api-key})
})(TestMap);
export {TestMap, GoogleApiWrapper};
here:
import React, { Component } from 'react';
import {TestMap} from '../components/map/google/TestMap';
class Map extends Component {
render() {
return (
//???
);
}
}
export default Map;
It's a react component, render it as JSX
import React, { Component } from 'react';
import { TestMap } from '../components/map/google/TestMap';
class Map extends Component {
render() {
return (
<TestMap />
);
}
}
export default Map;
An aside, don't name your class component Map as there is already a Javascript Map object and this could be the cause for some major confusion and bugs.
EDIT
Your map is forever loading as you've exported the undecorated TestMap, i.e. it isn't decorated with the google api and props.
import React, { Component } from "react";
import {Map, GoogleApiWrapper} from 'google-maps-react';
class TestMap extends Component {
render() {
return (
<div className="GoogleMap">
<Map google={this.props.google} zoom={14} />
</div>
);
}
}
// default export the decorated component so the api-key and google prop is processed and injected.
export default GoogleApiWrapper({
apiKey: 'sLiGhTlyReDacTedApIkEy'
})(TestMap);
You need to return your component as JSX markup, Introducing JSX.
Also if you are new to react is suggest starting here, Getting Started.
import React, { Component } from 'react';
import {TestMap} from '../components/map/google/TestMap';
class Map extends Component {
render() {
return (
<TestMap />
);
}
}
Specify the component inside the return block.In your case <TestMap /> inside the return of Map component.
Firstly I am not able to understand why are you adding one more abstraction of component over your Map component. You can directly use the TestMap component you have used in the first code snippet.
Anyway, You can directly return from the Map Component.
import React, { Component } from 'react';
import {TestMap} from '../components/map/google/TestMap';
class Map extends Component {
render() {
return (
<TestMap />
);
}
}
export default Map;
Child Component
import React from "react";
import {Map, GoogleApiWrapper} from 'google-maps-react';
class TestMap extends Component {
render() {
return (
<div className="GoogleMap">
<Map google={this.props.google} zoom={14} />
</div>
);
}
}
GoogleApiWrapper({
apiKey: ({api-key})
})(TestMap);
export default TestMap;
Parent Component
import React, { Component } from 'react';
import {TestMap} from '../components/map/google/TestMap';
class Map extends Component {
render() {
return (
<TestMap />
);
}
}
export default Map;

Update state for component by event handle in other component in different file?

I have two component in my project one is Tag and the other is LandingTicker so i want when i click Tag componet update state for LandTicker componet, and landticker componet in different file.
how i can do that?
thank you.
Tag component code::
tag/index.js
import React from 'react';
import './index.scss';
class Tag extends React.Component {
handleClick(e) {
let tags = document.querySelectorAll('.show-clickable');
Array.from(tags).map(el => el.classList.remove('selected-tag'))
e.target.classList.add('selected-tag');
/*
Here i should update the state for LandingTicker component.
and remember any component in different file.
How i can do that???
*/
}
render() {
return (
<div
className="show-clickable"
onClick={this.handleClick}
>
click here
</div>
);
}
}
export default Tag;
LandingTicker component code::
LandingTicker/index.js
import React from 'react';
import TickerRow from './TickerRow';
import './index.scss';
class LandingTicker extends React.Component {
state = {
coin: 'USD'
}
render() {
return (
<div className="landing-ticker__body">
{selectCoin(this.state.coin)}
</div>
</div>
);
}
}
const selectCoin = (coin) => {
const coins = {
USD: ['BTCUSD', 'ETHUSD', 'EOSUSD', 'LTCUSD'],
EUR: ['BTCEUR', 'ETHEUR', 'EOSEUR'],
GBP: ['BTCGBP', 'EOSGBP'],
JPY: ['BTCJPY', 'ETHJPY'],
};
return (
coins[coin].map(el =>
<TickerRow symbol={el} key={el.toString()} />
)
);
}
export default LandingTicker;
Edit:
my component Hierarchy::
StatusTable
TagsTable
Tag
TickerSearch
LandingTickers
TickersRow
StatusTable component code::
import React from 'react';
import TagsTable from './TagsTable';
import TickerSearch from './TickerSearch';
import LandingTicker from './LandingTicker';
import './StatusTable.scss';
class StatusTable extends React.Component {
render() {
return (
<div className="status-table">
<TagsTable />
<TickerSearch />
<LandingTicker />
</div>
);
}
}
export default StatusTable;
React handle all its component data in the form of state and props(immutable). So it is easy to pass data from parent to child or one component to another using props :
Your Tag.js file:
import React, { Component } from "react";
import LandingTicker from "./LandTicker";
class Tag extends Component {
constructor(props) {
super(props);
this.state = {
trigger: true
};
}
handleClick(e) {
// do all logic here and set state here
this.setState({ trigger: this.state.trigger });
}
render() {
//And then pass this state here as a props
return (
<div className="show-clickable" onClick={this.handleClick}>
click here
<LandingTicker trigger={this.state.trigger} />
</div>
);
}
}
export default Tag;
Inside LandTicker.js file:
import React from 'react';
import TickerRow from './TickerRow';
import './index.scss';
class LandingTicker extends React.Component {
state = {
coin: 'USD'
}
render() {
//Catch your props from parent here
//i.e this.props(it contains all data you sent from parent)
return (
<div className="landing-ticker__body">
{selectCoin(this.state.coin)}
</div>
);
}
}
const selectCoin = (coin) => {
const coins = {
USD: ['BTCUSD', 'ETHUSD', 'EOSUSD', 'LTCUSD'],
EUR: ['BTCEUR', 'ETHEUR', 'EOSEUR'],
GBP: ['BTCGBP', 'EOSGBP'],
JPY: ['BTCJPY', 'ETHJPY'],
};
return (
coins[coin].map(el =>
<TickerRow symbol={el} key={el.toString()} />
)
);
}
export default LandingTicker;
I think this is the best answer for your question if you don't use state management system such as Redux or Mobx.
https://medium.com/#ruthmpardee/passing-data-between-react-components-103ad82ebd17
(you need to check third option)

React useContext throws Invalid hook call error

I am trying to pass a value from a context provider to a consumer using useContext and access the value outside of the render function.
My provider looks like so:
export const AppContext = React.createContext();
export class App extends React.Component(){
render(){
<AppContext.Provider value={{ name: 'John' }} ><Main /></AppContext>
}
}
My consumer looks like so
import React, { useContext } from 'react';
import { AppContext } from './App';
export class Main extends React.Component(){
componentDidMount(){
const value = useContext(AppContext);
}
render(){
return (
<div>Main Component</div>
)
}
}
The error is this:
Invalid hook call. Hooks can only be called inside of the body of a function component.
If you want to use hooks they are designed for function components. Like so:
import React, { useContext } from 'react';
import { AppContext } from './App';
const Main = () => {
const value = useContext(AppContext);
return(
<div>Main Component</div>
);
}
If you want to use it in a class based component then just set it as a static contextType in your class and then you can use it with this.context in your component like so:
import React from 'react';
import { AppContext } from './App';
class Main extends React.Component(){
static contextType = AppContext;
componentDidMount(){
const value = this.context;
}
render(){
return (
<div>Main Component</div>
)
}
}
Edit:
Remove your context from your app component and place it in its own component. I think you are receiving conflicts in your exporting of your context.
so your app component should look like:
import React from "react";
import Context from "./Context";
import Main from "./Main";
class App extends React.Component {
render() {
return (
<Context>
<Main />
</Context>
);
}
}
export default App;
Your main component should be like:
import React from "react";
import { AppContext } from "./Context";
class Main extends React.Component {
static contextType = AppContext;
render() {
return <div>{this.context.name}</div>;
}
}
export default Main;
and your context component should be like:
import React from "react";
export const AppContext = React.createContext();
class Context extends React.Component {
state = {
name: "John"
};
//Now you can place all of your logic here
//instead of cluttering your app component
//using this components state as your context value
//allows you to easily write funcitons to change
//your context just using the native setState
//you can also place functions in your context value
//to call from anywhere in your app
render() {
return (
<AppContext.Provider value={this.state}>
{this.props.children}
</AppContext.Provider>
);
}
}
export default Context;
Here is a sandbox to show you it working CodSandbox
You get the above error because Hooks are meant to be used inside functional components and not class component whereas you try to use it within componentDidMount of Main component which is a class component
You can rewrite your code for Main component using useContext hook like
import React, { useContext } from 'react';
import { AppContext } from './App';
export const Main =() =>{
const value = useContext(AppContext);
return (
<div>Main Component</div>
)
}
or use Context in a different way with class like
import React from 'react';
import { AppContext } from './App';
class Main extends React.Component {
componentDidMount(){
const value = this.context;
// use value here. Also if you want to use context elsewhere in class
// you can use if from this.context
}
render(){
return (
<div>Main Component</div>
)
}
}
Main.contextType = AppContext;
export { Main };
Hooks only work with stateless components. You are trying to use it in class component.
Here is the content for Main.js file. Uncomment the commented part if you want to use class-based component instead of the functional one.
import React from "react";
import { AppContext } from "./App";
/** UNCOMMENT TO USE REACT CLASS COMPONENT */
// class Main extends React.Component() {
// render() {
// return (
// <AppContext.Consumer>
// {value => <div>It's Main component. Context value is ${value.name}</div>}
// </AppContext.Consumer>
// );
// }
// }
const Main = () => {
const value = React.useContext(AppContext);
return <div>It's Main component. Context value is ${value.name}</div>;
};
export default Main;
Here is the content for App.js file. Uncomment the commented part if you want to use class-based component instead of the functional one.
import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
export const AppContext = React.createContext();
/** UNCOMMENT TO USE REACT CLASS COMPONENT */
// export class App extends React.Component() {
// render() {
// return (
// <AppContext.Provider value={{ name: "John" }}>
// <Main />
// </AppContext.Provider>
// );
// }
// }
const App = () => (
<AppContext.Provider value={{ name: "John" }}>
<Main />
</AppContext.Provider>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
React Hooks were implemented directly for the functional components in order to give them the possibility to become stateful. Class-based components were stateful all the time, so you have to use their own state API.
Working demo is available here.

React.createElement: type should not be null, undefined.. When creating/rendering components

So the full error is as follows...
Warning: React.createElement: type should not be null, undefined,
boolean, or number. It should be a string (for DOM elements) or a ReactClass (for
composite components). Check the render method of `IndexBody.
I'm not sure why I'm receiving this error, I thought I created my component properly but maybe another eye can see what I'm doing wrong.
index.jsx:
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Test from './app';
class IndexBody extends React.Component {
render() {
return (
<div>
<h1>This will show the Test Component</h1>
<Test />
</div>
);
}
}
ReactDOM.render(<IndexBody />, document.getElementById('react-app'))
And my imported Test component from ./app.jsx
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
hello: 'hello world',
};
}
render() {
console.log('WORKS'); // logs fine
return (
<div>
<h1>{this.state.hello}</h1>
</div>
);
}
}
ReactDOM.render(<Test/>, document.getElementById('react-app'));
I'm able to display the log, but it doesn't want to render the component. Am I incorrectly creating components? Thank you for your help in advance!
You don't export Test from app.jsx.
This means it's not available as an import, thus the undefined.
Based on your current code you'd need to add:
export default Test;
to app.jsx.
Dave is correct, you need to do export default Test; at the bottom of App.jsx. Also, you only want one ReactDOM.render() function in you entire app, index.jsx loads the component tree it all gets passed to ReactDOM.render() in the one file (index.jsx).
So in your case just change app.jsx to this and you should be in business:
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
hello: 'hello world',
};
}
render() {
console.log('WORKS'); // logs fine
return (
<div>
<h1>{this.state.hello}</h1>
</div>
);
}
}
export default Test;

Categories