could you please tell me why I am getting this error:
Objects are not valid as a React child (found: object with keys
{seo_val, text_val}). If you meant to render a collection of children,
use an array instead.
I am trying to hit http request and try to make dropdown .
import React from "react";
class DropDown extends React.Component {
constructor(props) {
super(props);
console.log(this.props);
}
render() {
const makeDropDown = () => {
console.log(this.data);
return this.props.data.map(x => {
return <option>{x}</option>;
});
};
return (
<div>
<div>
<select>{makeDropDown()}</select>;
</div>
</div>
);
}
}
export default DropDown;
Sandbox.
Full error message:
Objects are not valid as a React child (found: object with keys
{seo_val, text_val}).
Error is very clear, you are trying to render an object in jsx that contains two keys:
seo_val: "..."
text_val: "..."
Write it like this, (render the value that you want):
return <option key={x.seo_val}>{x.text_val}</option>;
Working sandbox.
Looks like x is an object.
Try
import React from "react";
class DropDown extends React.Component {
constructor(props) {
super(props);
console.log(this.props);
}
render() {
return (
<div>
<div>
<select>{
this.props.data.map(x => {
return (<option key={x}>echo</option>);
})
}</select>;
</div>
</div>
);
}
}
export default DropDown;
And you'll see it works. Replace echo with {x} throws the error you mentioned.
Related
The following code works:
import React, { Component } from 'react';
import './App.css';
import Menu_dropdown from "./component/menu_dropdown";
class App extends Component {
constructor() {
super()
this.state = {
races: {}
}
}
componentDidMount(){
fetch('https://www.dnd5eapi.co/api/races/')
.then(response=> response.json())
.then(races => {this.setState({ races : races})});
}
render(){
const { races } = this.state;
console.log(races['results']);
return (
<div className="App">
<header className="App-header">
<Menu_dropdown races = {races}/>
</header>
</div>
);
}
}
export default App;
console will output an array of races. However,it gives me "TypeError: Cannot read property '0' of undefined" when I change to this
console.log(races['results'][0]);
why is results not an array? You can view source json here:
https://www.dnd5eapi.co/api/races/
When state is first initialized to { races: {}}, races.results will be undefined and you can't get any elements from undefined.
Simply change the constructor to:
constructor() {
super()
this.state = {
races: {results: []}
}
}
This way the component can render an empty array while loading and the fetch results when the fetch call is resolved.
this.state.onlyvar.TheName is showing up as undefined and I don't know why.
import React, { Component } from 'react';
class Thevar extends Component {
constructor(props) {
super(props);
this.state = {
onlyvar: [{
TheName:"getter Name"
}]
}
}
render() {
return (
<div>
TheOnlyVar: <p>{console.log(this.state.onlyvar.TheName)}</p>
</div>
)
}
}
export default Thevar;
In your code there are two mistakes:
onlyvar is an array, to access its items you should use an index to specify which item you want, in this case, the first (and only) item.
console.log() prints the value in the console, not on the page.
Here is the corrected code:
return (
<div>
TheOnlyVar: <p>{this.state.onlyvar[0].TheName}</p>
</div>
)
I'm super confused here, I'm trying to follow this question yet keep getting the error objects aren't valid as a react child. Or property is undefined.
The api response should be something like [{id:1, name: hugo}, {id:2, name:sally}]
What is causing these errors, why isn't the Component will mount lifecyle component changing state onload.
And why if I try to console.log the results of this do i get undefined.
import React, { Component } from 'react';
import { Button, Form } from "semantic-ui-react";
import { api31Call } from '../helpers';
import ItemLister from './ItemLister';
export default class PulseInputForm extends Component {
constructor(props) {
super(props)
this.state = {
data: [],
}
}
fetchData = () => {
api31Call('GET', '/projects')
.then(data => {
this.setState({
loading: false,
data: data
})
})
}
componentWillMount() {
this.setState({loading: true})
this.fetchData()
}
render() {
return(
<div>
{this.state.data.map((object, index) => (
<p key={index}>{object}</p>
))}
</div>
)
}
}
You can not render object. You can show only text.
{this.state.data.map((object, index) => (
<p key={index}>{object}</p>
))}
</div>
)
The object in your code means each item of array like {id:1, name: hugo}
So, I think name is what you want to show. Please use object.name to show each name
And you should not use index in key. It is better to use primary key in your data like id
change like this
{this.state.data.map((object) => (
<p key={object.id}>{object.name}</p>
))}
You need to render object field not object.
{this.state.data.map((object, index) => (
<p key={index}>{object.name}</p>
))}
I am having a child component a parent component. I am having a function in child component which returns some jsx what i want to do is use that function to return the same jsx in parent component but iam unable to figure out a way to do that. I am giving my minimal code:
parent component:
class App extends Component {
render() {
return (
<div className="App">
<Player ref={instance=>{this.player = instance}} />
{this.player.func('aaa.com','bbb')}
</div>
);
}
}
export default App;
Child component:
import React, { Component } from "react";
class Player extends Component {
func = (url, label) => {
return (
<button onClick={() => this.func(url)}>
{label}
</button>
)
}
render() {
return <div>1</div>;
}
}
export default Player;
Error: Cannot read property 'func' of undefined
//
Note: i know i can use the jsx in parent component by copy-pasting but iam trying to figure out a way of doing like this. I am having doubt that is it even possible
You can create a Player object and access the function using that object.
new Player().func('aaa.com','bbb')
I don't quite understand what you need exactly but I think that you're looking to pass some jsx element from the Child component to the parent component. What we can do is declare a propType callback on the child component and then implement it on the parent component like so.
import React from 'react';
class Hello extends React.Component {
constructor() {
super();
this.state = {
// this state will keep the element returned by the parent
returnElements: null
}
this.onReturn = this.onReturn.bind(this);
}
// this method will be fired when the Child component returns callback for onSomethingReturned
onReturn(element) {
this.setState({
returnElements: element
})
}
render () {
return (
<div>
<h1>Hello, React!</h1>
<Child onSomethingReturned={this.onReturn} />
{/* I am going to display the state here */}
{this.state.returnElements}
</div>
)
}
}
class Child extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
const element = <h3>this is child element</h3>;
// will call the propType callback function with a element I want to return
this.props.onSomethingReturned(element);
}
render() {
return (null);
}
}
export default Hello;
I have done this before and I am providing a key, but for some reason I am still getting the error. I am a bit new to react so it could be a silly mistake somewhere.
Edit: Error is the each child in an array should have a unique key
Here is the code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';
class BooksList extends Component {
renderList() {
return _.map(this.props.books, book => {
return (
<div key={book.id}>
<h2>{book.title}</h2>
<h3>{book.description}</h3>
<h4>{book.price}</h4>
</div>
);
});
}
render() {
return (
<div>
{this.renderList()}
</div>
);
}
}
function mapStateToProps(state) {
return {
books: state.books
}
}
export default connect(mapStateToProps)(BooksList);
Edit:
I tried binding this.renderList, in the constructor, but still have the same issue:
constructor(props) {
super(props);
this.renderList = this.renderList.bind(this);
}
Your issue is you are not loading the books before the map happens initially.. so you have invalid data initially.
Initially this.props.books is this
then you load the books and it turns to this.
The fix for this is to only render when you have a valid object. Use the lodash isEmpty check for an object... use a forEach so you dont return empty in an array (less items to hold in array). and then just return that array at the end :)
renderList() {
const elems = [];
_.forEach(this.props.books, book => {
if (_.isEmpty(book)) return;
elems.push(
<div key={book.id}>
<h2>{book.title}</h2>
<h3>{book.description}</h3>
<h4>{book.price}</h4>
</div>
);
});
return elems;
}