Uncaught error: Objects are not valid as a React child - javascript

I'm really new to react, im trying to build an app in that library, however i keep running into this error and i don't know what it does nor how to resolve it.
I'm just trying to pass data from a parent component to a child component, previously i was trying to do that from a fetch and from an array but now it's just basic props and still i get this error.
the parent component
import axios, * as others from 'axios';
import Row from 'react-bootstrap/Row';
import Cerd from "./Cerd";
import movieArray from "./MovieArray";
export function UseFetch(message){
let number = movieArray.length;
console.log(number);
let image = movieArray[0].image;
let text = movieArray[0].title;
let actors = movieArray[0].actors;
const toStringer = text.toString();
console.log(toStringer);
return(
<div className="row-wrapper">
<Row>
<Cerd title="ciao"/>
</Row>
</div>
)
}
the child component:
mport Card from 'react-bootstrap/card';
export default function Cerd(title){
console.log(title);
return(
<div>{title}</div>
)
}
Here's the error:
I already tried to change computer and search for solutions online but nothing changes, I0m not passing an array or an object in the props as it is just a simple string. This is a killer error because it's not the first time that happens to me and i still haven't found what to do when it happens... can somebody help?
EDIT: I was asked to post the movieArray component, so here it is:
const movieArray = [{
title: "ciao",
actors: "celine dion",
image: "./public/logo192.png"
},{
title: "ciao",
actors: "celine dion",
image: "./public/logo192.png"
},{
title: "ciao",
actors: "celine dion",
image: "./public/logo192.png"
}]
export default movieArray;

In react component props passing, you cannot take it like taking from function.
You defined "title" in props of component, but you cannot take it as a variable. You have to take it as shorthand.
// your code;
export default function Cerd(title){
// must be;
\/
export default function Cerd({title}){
Try ({title}) instead of (title).

Related

How to type state in React Hooks without adding typescript (like prop-type - in a simple way)

Just wonder.
If I don't want to add TS to my React project, but I need sometimes some types checking.
While for props I have a simple solution of prop-types, for state I can't do nothing.
So is there is some solution for that?
import PropTypes from 'prop-types';
//https://reactjs.org/docs/typechecking-with-proptypes.html - prop-types
export function GreetingHook (props) {
const [name2, setName2] = useState(10);//won't generate a warning.
{
return (
<h1>Hello, {props.name}</h1>
);
}
}
GreetingHook.propTypes = {
name: PropTypes.string,
name2: PropTypes.string
};
//Some parent...
//Will generate a warning
<GreetingHook name = {5}/>
NB - The same question should be asked about class component too.
You can use flow instead of typescript, and for typechecking you can do it in this way :
const [name2, setName2] = useState(10);
(name2: number);

React props not showing up in the Child component (but I can see they exist in debug mode)

I have been creating a simple React project (not using Redux) and I'm having issues passing the state from the parent into the Child component. I've watched multiple tutorials and went through with the Chrome debugger and still cannot figure out the issue.
I am passing a list of song-tracks from the Parent (App) to the Child (PlaylistOptions), however, when I log the list of songs it is empty until like the 3rd load (screenshot attached). Another weird thing that happens is I'm able to access the first song right away but makes the whole app crash. I have tried changing my child from a function to a class, and also have added a componentWillMount in the child with a wait time for the props to load but nothing solved my problem.
Here is how I'm passing the state into the child component:
<PlaylistOptions
wait={5000}
items={this.state.items}
next={this.state.next}
previous={this.state.previous}
offset={this.state.offset}
limit={this.state.limit}
token={this.state.token}
/>
This is what the console shows of my items array (the array is empty until the 3rd load I have no idea why)
result of logging items array
Errors from trying to access the second element of the array
error in browser
error in console
It looks like you're trying to access the 2nd element of the items array being passed in as a prop. Take a look at how many items are in the items array in your initial state. You're trying to access an item that doesn't exist, and that's throwing an error.
Instead of accessing the indices of the array directly, you can map over the array to generate a list dynamically based on the number of entries in the array.
<div>
Song List
{this.props.items.map((item, i) => {
return(`Song ${i} - ${item.track.name}`);
})}
</div>
Here is the complete example of how you pass data from parent component to child component in React:
Parent Component
import React, {Component, useEffect, useState} from 'react';
import PChild from "./PChild";
class Parent extends Component {
constructor(props) {
super(props);
this.state = {items: []};
}
componentDidMount() {
let json = [];
json.push({track: { id:1, name: 'Black Sabbath, from the album Black Sabbath (1970)'}});
json.push({track: { id:2, name: 'Blackfield, from the album Blackfield (2004)'}});
json.push({track: { id:3, name: 'Bo Diddley, from the album Bo Diddley (1958)'}});
json.push({track: { id:4, name: 'Damn Yankees, from the album Damn Yankees (1990)'}});
this.setState({items: json});
}
render() {
return (
<div>
<PChild items={this.state.items}/>
</div>
);
}
}
export default Parent;
Child Component
import React, {useEffect, useState} from 'react';
// Parent to Child communication
class PChild extends React.Component {
render() {
return (
<div>
{this.props.items.map((item, i) => {
return <li key={item.track.id}>
{(`Item ${i+1} - ${item.track.name}`)}
</li>
})}
</div>
);
}
}
export default PChild;

Why Does My React App Keep Failing To Compile?

I'm learning react and building a simple straightforward to do list app. However, it keeps throwing this error:
./src/App.js
Line 9:35: 'Todo' is not defined react/jsx-no-undef
Search for the keywords to learn more about each error.
I'm not sure why this error keeps throwing. I have defined my my ToDo js file - I believe I correctly exported it and then correctly imported in the App js file. Am I missing something?
App.Js File:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import ToDo from './ToDo.js'
import DoData from './DoData.js'
function App() {
const val = DoData.map(item => <Todo key = {item.id} item = {item}/>)
return (
{val}
);
}
export default App;
ToDo.js file:
import React from 'react'
function Todo(props){
return(
<div className = "todo-item">
<input type ="checkbox" checked = {props.things.completed}></input>
<p>{props.things.description}</p>
</div>
)
}
export default Todo
DoData.js:
let DoData = [
{
id: 1,
description: "go for a walk",
completed: true
},
{
id: 2,
description: "babysitting",
completed: true
},
{
id: 3,
description: "watch MadMen",
completed: false
},
{
id: 4,
description: "See the mailman",
completed: true
},
{
id: 5,
description: "Say hello to the world",
completed: false
}
]
export default DoData.js
In JavaScript, identifiers are case-sensitive
Check the case of the identifier in your import statement in the file ./App.Js vs the use of it:
import ToDo from './ToDo.js'
<Todo ... />
Notice the difference in casing between Todo & ToDo. You have 2 options to fix this linting error.
Either change your import to:
import Todo from './ToDo.js'
or
change your use to:
`<ToDo ... />`
Note: Also, double check your export statement in the file ./DoData.js.
While the identifier DoData definitely exists, it has no property called js, and so DoData.js will be undefined.
Option 1
Update
import ToDo from './ToDo.js'
to
import Todo from './ToDo.js'
as you are using <Todo key = {item.id} item = {item}/> in your app
Option 2
Update
<Todo key = {item.id} item = {item}/>
to
<ToDo key = {item.id} item = {item}/>
as you are importing component as ToDo
import ToDo from './ToDo.js'
As you are exporting ToDo as default in ToDo.js file, you can use it as any name as you want in your imports anywhere in your app. But make sure when you render the component, it matches the import name at top.

How to pass down data through 3 class components in react correctly?

This is a react beginners exercise, so please be patient and don't overwhelm with the latest best practice.
For this exercise I need 3 class components:
Main.js: which basically just holds an array
List.js: which maps through that array and with each iteration passes the element of the array to Item.js
Item.js: here you render the mapped array
I am quite confident with the first two components but unable to make the jump from 2 to 3. Who can not only post the answer but also comment out the key ideas? Thx!
What I have so far for Main.js and List.js
Main.js
import React from "react";
export const avengers = ["Ironman", "Thor", "Hulk", "Hawkeye", "Black Widow"]
List.js
import React from "react";
import Main, { avengers } from "Main.js";
class List extends React.Component {
render() {
return (
<div>
{avengers.map((superhero, index) =>
<Item key={index} superhero={superhero}/>
)}
</div>
);
}
}
export default List;
Item.js
import React from "react";
import ReactDOM from "react-dom";
import List from "./List.js";
class Item extends React.Component {
render() {
return (
<div>
{this.props.superhero}
</div>
);
}
}
export default Item;
One problem you have is when passing props
<Item key="index" superhero="{superhero}" />
You should be passing it like
<Item key={index} superhero={superhero} />
If you put is ass someProp="something" you are just passing a string.
If you want to pass a variable, you need to pass it like someProp={someVariable}
And the prop can be access inside Item like this.props.someProp (if it's a class component, or props.someProp if is a functional component, where props is the parameter of your functional component.
Edit
One mistake I just saw in your code is these two lines
const avengers = ["Ironman", "Thor", "Hulk", "Hawkeye", "Black Widow"]
and
import avengers from "Main.js";
In the first line, you create avangers but you never export it, so you want be able to import it.
What you need to do is add export and when importing, import it by the name (inside {}) because the way you are importing, you are getting the default export.
So here is how it should be
// added export
export const avengers = ["Ironman", "Thor", "Hulk", "Hawkeye", "Black Widow"]
and
// importing avengers correctly
import Main, { avengers } from "Main.js";
Edit 2
Not sure if this is what you want, but I will guess
class Item extends React.Component {
render() {
return (
<div>
{this.props.superhero}
</div>
);
}
}
export default Item;
Last Edit
I made you a codesandbox with a working example. Please take a look and see how it works, play around with it and try to learn from it. Hope this helps ;)

Passing props to children not working In React

This should be super simple for some of you. I have a super simple app that I am making to teach myself the glory that is React and reactDom. Currently, I am pulling from an API (which actually works!), however, I am unable to see any data when rendering to the screen. Literally just two components. I am sure that I am using props or state wrong here, I just don't know where. It's possible that my map function is the problem as well.
Here is the code:
Parent:
import React from "react";
import ReactDOM from "react-dom";
import axios from 'axios'
import { Table } from './Table'
export class DataList extends React.Component {
state = {
articles: []
}
componentDidMount() {
axios.get('http://127.0.0.1:8000/api/portblog/')
.then(res => {
this.setState({
articles: res.data
})
console.log(res.data)
})
}
render() {
return(
<div>
<Table id={this.state.articles.id} articles={this.state.articles} />
</div>
)
}
}
export default DataList
And the child:
import React from "react";
import PropTypes from "prop-types";
import key from "weak-key";
export const Table = (props) => (
<div>
<h1>Welcome to the Article List Page Home</h1>
<li>{props.articles.map((article) => {
{article.titles}
})}</li>
</div>
);
export default Table;
The problem is that your map() call is not returning anything. You need to do something like:
<div>
<h1>Welcome to the Article List Page Home</h1>
{props.articles.map(article =>
<li>{article.titles}</li>
)}
</div>
I'm not exactly sure what your desired output is, but generally you map over data to generate a set of dom elements.
The problem is
<li>{props.articles.map((article) => {
{article.titles}
})}</li>
JSX expressions cannot be used in any arbitrary place. props.articles.map(...) is already an expression, so creating a new one wouldn't make sense.
{article.titles} inside a function creates a block that does nothing. Nothing is returned from map callback, the array isn't mapped to anything.
Depending on what should resulting layout look like, it should be either
<li>{props.articles.map((article) => article.titles)}</li>
output titles within single <li> tag, or
{props.articles.map((article) => <li>{article.titles}</li>)}
to output a list of <li> tags.
ESLint array-callback-return rule can be used to prevent the problem with callback return value.

Categories

Resources