i am new to React and i hope this doesn't sound stupid.
a little bit of context here: i have a ExerciseCard
component that has a checkbox,(and other stuff), this component is rendered inside CreateNewWorkout
and here i do fetch DATA from an API, so now i want to get all the ExerciseCard
components that has its checkBox selected in a list that has the name of that component (in the state it's called 'name' and in the api it's called 'exerciseName').
here is my code
the CreateComponent
import React from "react";
import ExerciseCard from "../component/ExerciseCard";
import { Row } from "antd";
import WorkoutModal from "../component/WorkoutModal";
class CreateNewWorkout extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.changed = this.changed.bind(this);
}
// this is the onChange event handlet
changed = (e) => {
console.log(e.target.checked);
};
async componentDidMount() {
let response = await fetch("http://localhost:1337/calisthenics-exercices");
const data = await response.json();
// i used "objecto" to store an array of objects in state later
const objecto = [];
data.map((item) =>
objecto.push({
id: item.id,
name: item.exerciceName,
discription: item.discription,
// the json file has another object file called 'type' inside it for every item
type: item.type.type,
imageURL: item.imgURL,
youtubeURL: item.youtubeURL,
})
);
this.setState(objecto);
}
render() {
return (
<>
<div
style={{
position: "fixed",
bottom: 0,
zIndex: 2,
}}
>
<WorkoutModal></WorkoutModal>
</div>
<Row>
{Object.entries(this.state).map((item) => (
<ExerciseCard
title={item[1].name}
type={item[1].type}
key={item}
description={item[1].discription}
// image={item[1].imageURL}
youtubeURL={item[1].youtubeURL}
//changed for onChange event
changed={this.changed}
></ExerciseCard>
))}{" "}
}
</Row>
{console.log(this.state)}
</>
);
}
}
export default CreateNewWorkout;
the ExerciseCard
if you need it
import React from "react";
import { Col } from "antd";
import ExerciseModal from "./ExerciseModal";
import { Card, Tag, Checkbox } from "antd";
//import Title from "antd/lib/skeleton/Title";
//import { formatCountdown } from "antd/lib/statistic/utils";
const { Meta } = Card;
function ExerciseCard(props) {
function tagColor() {
switch (props.type) {
case "core":
return "magenta";
case "lower body":
return "volcano";
case "horizontal push":
return "cyan";
case "horizontal pull":
return "blue";
case "vertical pull":
return "geekblue";
case "vertical push":
return "purple";
default:
return "black";
}
}
return (
<Col xs={12} sm={8} md={6} lg={4}>
<Card>
<Meta title={props.title} />
<Tag
style={{ position: "absolute", top: 0, left: 0 }}
color={tagColor()}
>
{props.type}
</Tag>
<Checkbox
onChange={props.changed}
style={{
padding: "20px 0 0 0",
}}
></Checkbox>
<ExerciseModal
title={props.title}
description={props.description}
youtubeURL={props.youtubeURL}
></ExerciseModal>
</Card>
</Col>
);
}
export default ExerciseCard;
You could access the checkbox, using e.target
If you need something particular as user-defined data (such as id, name or something else, you could define your change
function as following:
changed = (e, title) => {
console.log(e.target.checked);
};
Please note, that you have already defined the function as arrow function
and you don't have to bind this
in your constructor.
Then pass the function to ExcerciseCard
the same way you are doing it now. Finally call the function in the following way:
<Checkbox
onChange={e => props.changed(e, props.title)}
style={{
padding: "20px 0 0 0",
}}
></Checkbox>
I wrote an example with title
, but feel free to change it, so it fits your needs.