Hi I'm trying to pass and render input values from AddHamster (child) component to HamsterCard Component (parent). I'm getting the error message: Error: Objects are not valid as a React child (found: object with keys {name, age, render}). If you meant to render a collection of children, use an array instead.
Any clue on how I could solve this?
import React, {useState} from "react";
const AddHamster = () => {
const [name, setName] = useState( '')
const [age, setAge] = useState('')
async function postHamster(){
const newHamster = {
name: name,
age: Number(age),
}
const response = await fetch('/hamsters ', {method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(newHamster)
})
const data = await response.json()
console.log(data, "this is data id");
console.log(newHamster)
}
return {
name,
age,
render: (
<div className="add-hamster">
<form onSubmit={e => { e.preventDefault(); }}>
<label>Name</label>
<input value={name}
type="text"
onChange={(e) =>setName(e.target.value)}
id="addhamster" />
<label>Age</label>
<input value={age}
type="text"
onChange={(e) =>setAge(e.target.value)}
id="addhamster" />
</form>
<button onClick={e => postHamster()}>Add Hamster</button>
</div>
)}
}
export default AddHamster;
AddHamster.jsx `
import React, {useState, useEffect} from "react";
import './HamsterCard.css';
import Hamster from './Hamster';
import AddHamster from './AddHamster.jsx';
const HamsterCard = () => {
const {render, name, age} = AddHamster();
const [hamsters, setHamsters] = useState([])
useEffect(() => {
async function get(){
const response = await fetch('/hamsters', {method: 'GET',})
//fetchar och tar emot data i reponsens
const data = await response.json() //Data
setHamsters(data)
console.log(data)
}
get()
}, [] );
return (
//pass the id inside of the delete function to which id to delete
<div className="container">
<div className="hamster-card">
{hamsters.map((hamster) => (
<Hamster hamster={hamster}
key={hamster.id} {...{name, age}}/>
))
}
{render}
</div>
</div>
)
}
export default HamsterCard;
HamsterCard.jsx
import React, {useState} from "react";
const Hamster = (props) => {
const [hamsterDeleted, setHamsterDeleted] = useState(false)
async function deleteHamster(id) {
const response = await fetch(`/hamsters/${id}`, { method: "DELETE" });
setHamsterDeleted(true)
}
return (
hamsterDeleted ? null : (
<div>
<button onClick={() => deleteHamster(props.hamster.id)}>Delete</button>
<h2>{props.hamster.name}</h2>
<p>Ålder:{props.hamster.age}</p>
<p>Favorit mat:{props.hamster.favFood}</p>
<p>Matcher:{props.hamster.games}</p>
<img src={'./img/' + props.hamster.imgName} alt="hamster"/> )
</div>
))
}
export default Hamster;
import React, {useState} from "react";
const AddHamster = () => {
const [name, setName] = useState( '')
const [age, setAge] = useState('')
async function postHamster(){
const newHamster = {
name: name,
age: Number(age),
}
const response = await fetch('/hamsters ', {method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(newHamster)
})
const data = await response.json()
console.log(data, "this is data id");
console.log(newHamster)
}
return {
name,
age,
render: (
<div className="add-hamster">
<form onSubmit={e => { e.preventDefault(); }}>
<label>Name</label>
<input value={name}
type="text"
onChange={(e) =>setName(e.target.value)}
id="addhamster" />
<label>Age</label>
<input value={age}
type="text"
onChange={(e) =>setAge(e.target.value)}
id="addhamster" />
</form>
<button onClick={e => postHamster()}>Add Hamster</button>
</div>
)}
}
export default AddHamster;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
{render}in the HamsterCard component? 'render' is a function, not the component itself. I think if you remove that line it should work. If you want to display the AddHamster component, simply include that instead of render, i.e.<AddHamster />