how to add onClick function to array - arrays

I am trying to add onClick function to this array. So when i click on "How will i get cashback?",output
it must display the items(Page Page One,Two) image and when i click on "Page Page One", it must display "Subcontent"
stackblitz
export default class Chat extends React.Component {
constructor(props) {
super(props);
this.state = {
message: [
{
id: 1,
title: "How will i get cashback?",
items: [
{
id: 1,
title: "Page Page One",
items: [
{
id: 1,
title: 'SubContent'
}
],
},
{
id: 2,
title: "Two",
},
],
},
{
id: 2,
title: "Reschedule delivery",
items: [],
},
],
};
}
render() {
const { message } = this.state;
return (
<div>
<p className={styles.titleText}>AAAAAA</p>
<div className={styles.line} />
{message.map((m) => (
<div>
<div
className={styles.button}
>
{m.title}
<i
className={`fa fa-chevron-right`}
aria-hidden="true"
/>
</div>
<div className={styles.line} />
</div>
))}
</div>
);
}
}

Add this change to your code.
Basically what you are telling your program is "If I have items, then set the state to be these items, else do nothing"
<div className={`button`} onClick={() => m.items ? this.setState({ message: m.items }) : null}>
{m.title}
<i className={`fa fa-chevron-right`} aria-hidden="true" />
</div>

Related

Props is not updating in class component React

I am Traying to pass props as product data object on clicking on that product in class component in react but element values are not getting assigned the following code for which am trying for plz help to solve this problem I am new at class component in react
class ProductList extends React.Component {
constructor() {
super()
this.state = {
product:undefined,
productsList: [
{
id: 1,
name: 'Samsung Galaxy Note 10',
category: 'Mobiles',
country: 'Canada',
price: 11500,
currencyCode: 'CAD',
productImage: require('./assets/img/product1.jpg'),
},
{
id: 5,
name: 'SkullCandy BT Inkd Plus',
category: 'Bluetooth Headset',
country: 'UK',
price: 800,
currencyCode: 'USD',
productImage: require('./assets/img/product2.jpg'),
}
],
}
}
render() {
return (
<>
<div className="ProductList">
<ul id="products" className="products">
{this.state.productsList.map((element, i) => (
<li
id={'product' + i}
onClick={() => this.setState({ product: 'abc' })}
>
<img id={'image' + i} src={element.productImage} />
<b>{element.name}</b>
</li>
))}
</ul>
</div>
<div className="productComponent">
{console.log(this.product)}
<Product productProp={this.product} />
</div>
</>
)
}
}
export default ProductList
Pass props as this.state.product instead of this.product
<Product productProp={this.state.product} />

State in react is not rendering/displaying to the screen

I'm not able get what I'm doing wrong here. Could someone please help me out here. I'm unable to print the value to the screen. I'm trying to print the value from the state to the screen but I'm unable to.
Its not showing any error. I know this could be a silly mistake. Please help me out. Thanks
I'm not able get what I'm doing wrong here. Could someone please help me out here. I'm unable to print the value to the screen. i'm trying to print the value from the state to the screen but i'm unable to.
Its not showing any error.
import React, { Component } from "react";
import "./Screen.css";
export default class Screen extends Component {
constructor(props) {
super(props);
this.state = {
roles: [
{ id: 1, value: "Contracts manager", isChecked: false },
{ id: 2, value: "In-house counsel", isChecked: false },
{ id: 3, value: "IT administrator", isChecked: false },
{ id: 4, value: "Law clerk", isChecked: false },
{ id: 5, value: "Legal administrator", isChecked: false },
{ id: 6, value: "Legal operations manager", isChecked: false },
{ id: 7, value: "Legal secretary", isChecked: false },
{ id: 8, value: "Paralegal", isChecked: false },
{ id: 9, value: "Procurement manager", isChecked: false },
{ id: 10, value: "Solicitor", isChecked: false },
{ id: 11, value: "Other", isChecked: false },
],
aksha: "aksk",
};
console.log(this.state);
}
roleHandler = (event) => {
let roles = this.state.roles;
roles.forEach((role) => {
if (role.value === event.target.value)
role.isChecked = event.target.checked;
});
this.setState({ roles: roles });
};
render() {
const newRoles = this.state.roles.map((role) => {
return (
<div className="border-inp">
<label className="checkbox">
<span className="checkbox__input">
<input
type="checkbox"
name="checkbox"
key={this.state.roles.id}
onClick={this.roleHandler}
value={this.state.roles.value}
checked={this.state.roles.checked}
/>{" "}
{this.state.roles.value}
</span>
</label>
</div>
);
});
return (
<div>
<div className="Screenbg">
<div id="viewport" className="screenview">
<h3 className="wel">Welcome</h3>
<div>
<h5 className="role">What is your role?</h5>
{newRoles}
</div>
<div className="grid-container btndiv">
{/* <div className="grid-child purple">
<button className="btn">Back</button>
</div> */}
<div className="grid-child green">
{/* <Link to="/"> */}
<button className="btn">Next</button>
{/* </Link> */}
</div>
</div>
</div>
</div>
</div>
);
}
}
role must be used for rendering your array. You were using state to get it.
render() {
const newRoles = this.state.roles.map((role) => {
return (
<div className="border-inp">
<label className="checkbox">
<span className="checkbox__input">
<input
type="checkbox"
name="checkbox"
key={this.state.roles.id}
onClick={this.roleHandler}
value={this.state.roles.value}
checked={this.state.roles.checked}
/>
{role.value}
</span>
</label>
</div>

Mapping of images to get particular data image on hover

Code below is an example of creation by me in code sandbox. I map sum of images and try to hover image and get that image details...if I hover on one image its getting all images data.
Can anyone help on this: https://codesandbox.io/s/romantic-haslett-qreg1?file=/src/App.js:0-1096
import React, { Component } from "react";
import "./styles.css";
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp") },
{ text: "sky", image: require("./images/sky.jpg") },
{ text: "tree", image: require("./images/tree.jpg") }
],
hover: false
};
}
Hover = () => {
this.setState({
hover: true
});
};
NotHover = () => {
this.setState({
hover: false
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={this.Hover}
onMouseLeave={this.NotHover}
src={image.image}
alt=""
/>
{this.state.hover &&
<div>
<li>{image.text}</li>
</div>}
</div>
))}
</div>
);
}
}
You could save a state for hover status of each image by its key
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp") },
{ text: "sky", image: require("./images/sky.jpg") },
{ text: "tree", image: require("./images/tree.jpg") }
],
hover: {
0: false,
1: false,
2: false
}
};
}
AddressMenuBox = (key) => () => {
this.setState({
hover: { [key]: true }
});
};
AddressMenuBoxLeave = (key) => () => {
this.setState({
hover: { [key]: false }
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={this.AddressMenuBox(key)}
onMouseLeave={this.AddressMenuBoxLeave(key)}
src={image.image}
alt=""
/>
{this.state.hover[key] && (
<div>
<li>{image.text}</li>
</div>
)}
</div>
))}
</div>
);
}
}
Codesandbox for implementation
You have to differentiate between the elements to force hover only on selected image, therefore you could provide additional id property to your images and change hover state to hoverTargetId so that it represents an id of selected item.
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ id: 0, text: "sun", image: require("./images/sun.webp") },
{ id: 1, text: "sky", image: require("./images/sky.jpg") },
{ id: 2, text: "tree", image: require("./images/tree.jpg") }
],
hoverTargetId: null
};
}
onHoverStart = targetId => () => {
this.setState({ hover: targetId });
};
onHoverEnd = () => {
this.setState({ hover: null });
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div key={key}>
<img
className="image"
onMouseEnter={this.onHoverStart(image.id)}
onMouseLeave={this.onHoverEnd}
src={image.image}
alt=""
/>
{this.state.hover === image.id &&
<div>
<li>{image.text}</li>
</div>
}
</div>
))}
</div>
);
}
}
The id i've introduced could be substituted by your iteration index (key), but it's a better practice to not handle such things based on dynamically generated values.
Change your code with the boolean variable to show target image:
import React, { Component } from "react";
import "./styles.css";
export default class Images extends Component {
constructor(props) {
super(props);
this.state = {
Images: [
{ text: "sun", image: require("./images/sun.webp"), show: false },
{ text: "sky", image: require("./images/sky.jpg"), show: false },
{ text: "tree", image: require("./images/tree.jpg"), show: false }
],
hover: false
};
}
AddressMenuBox = (key) => {
let items = [...this.state.Images];
let item = { ...items[key] };
item.show = true;
items[key] = item;
this.setState({
hover: true,
Images: items
});
};
AddressMenuBoxLeave = (key) => {
let items = [...this.state.Images];
let item = { ...items[key] };
item.show = false;
items[key] = item;
this.setState({
hover: false,
Images: items
});
};
render() {
return (
<div className="icon">
{this.state.Images.map((image, key) => (
<div>
<img
className="image"
onMouseEnter={() => this.AddressMenuBox(key)}
onMouseLeave={() => this.AddressMenuBoxLeave(key)}
src={image.image}
alt=""
/>
{this.state.hover && image.show && (
<div>
<li>{image.text}</li>
</div>
)}
</div>
))}
</div>
);
}
}
Edit code on sanbox:
https://codesandbox.io/s/distracted-gagarin-54zv4?file=/src/App.js:0-1462

map on react returns empty div

i'm using map to loop trough an array and then fill a div with it, but it's always empty:
Here's some of my code:
const [scoreOptions, setScoreOptions] = useState(initialScoreOption);
const initialScoreOption = [
{ id: 1, selected: false, icon: 'far fa-smile', label: 'lala'},
{ id: 2, selected: false, icon: 'far fa-meh', label: 'lalala'},
{ id: 3, selected: false, icon: 'far fa-frown', label: 'lalala'}
];
let iconosTexto;
if (scoreOptions){
iconosTexto = scoreOptions.map(icono => {
return(
<div className="contenedorIconoTexto">
<div className="iconoElemento">
<i className={blue ? `blueIcon ${icono.icon}` : `greyIcon ${icono.icon}`}>
</i>
</div>
<div className="iconoTexto">
{icono.label}
</div>
</div>
)
});
}
and then i have this on the render
<div className="container">
{ iconosTexto }
</div>
The div with the class container it's empty when it should be filled with all of the above
Can anyone help me with this?
Firstly, declare initialScoreOption before useState(initialScoreOption).
Use set key prop while rendering elements in map:
iconosTexto = scoreOptions.map((icono) => {
return (
<div key={icono.id} className="contenedorIconoTexto">
...
Then make sure that iconosTexto has always value.
Try this way :
const IconosTexto = () => scoreOptions.map(icono => {
return (
<div className="contenedorIconoTexto">
<div className="iconoElemento">
<i className={blue ? `blueIcon ${icono.icon}` : `greyIcon ${icono.icon}`}
>
</i>
</div>
<div className="iconoTexto">{icono.label}</div>
</div>
)
}
render (
<div className="container">
<IconosTexto />
</div>
)
You need to declare initialScoreOption before passing it to useState:
const initialScoreOption = [
{ id: 1, selected: false, icon: 'far fa-smile', label: 'lala'},
{ id: 2, selected: false, icon: 'far fa-meh', label: 'lalala'},
{ id: 3, selected: false, icon: 'far fa-frown', label: 'lalala'}
];
const [scoreOptions, setScoreOptions] = useState(initialScoreOption);
demo

Using Reactjs to align and display results based on Contestant ID

The code below displays three Election Contestants from the arrays.
Now I want to show their vote counts for each contestanst based on their Ids.
here is the arrays showing various contestant results that i want to merge based on their Id's
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" },
],
My issues is stated below:
Each time I run the code, all the three contestant are seen having 500 votes but in reality based on their Ids,
Contestant 1 should have 500 votes.
Contestant 2 should have 200 votes.
Contestant 3 should have 320 votes.
I guess I have to loop through the contestant Vote results arrays using something like map() functions as per the code below but do not know
how to apply it. Any help or solutions will be appreciated
{this.state.contestantResult.map((contestant, i) => {
//if (contestant.id == person.id) {
if (contestant.id) {
return (
<div key={i}>
<div>{contestant.voteCount}</div>
</div>
);
}
})}
Below is my coding efforts so far
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
class Contestant extends React.Component {
constructor() {
super();
this.state = {};
}
render() {
return (
<React.Fragment>
<div key={this.props.data.id}>
<div style={{ background: "black", color: "white" }}>
<b>Id:</b>
{this.props.data.id}
<br />
<b>Name:</b> {this.props.data.name}
<br />
<b style={{ color: "red" }}>Vote Count: {this.props.resultVotes}</b>
<br />
</div>
</div>
</React.Fragment>
);
}
}
class VoteResult extends React.Component {
constructor() {
super();
this.state = {
data: [
{ id: 1, name: "contestant 1" },
{ id: 2, name: "contestant 2" },
{ id: 3, name: "contestant 3" }
],
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" }
]
};
}
componentDidMount() {}
render() {
return (
<div>
<h1> Electoral College Voting......</h1>
{this.state.data.map(person => {
return (
<Contestant
key={person.id}
data={person}
resultVotes={this.state.contestantResult[0].voteCount}
/>
);
})}
</div>
);
}
}
You don't want to take the first object in the contestantResult array for every iteration in the loop. You could instead use find to find the result of the correct contestant.
{this.state.data.map(person => {
const result = this.state.contestantResult.find(res => res.id === person.id);
return (
<Contestant
key={person.id}
data={person}
resultVotes={result.voteCount}
/>
);
})}
class VoteResult extends React.Component {
state = {
data: [
{ id: 1, name: "contestant 1" },
{ id: 2, name: "contestant 2" },
{ id: 3, name: "contestant 3" }
],
contestantResult: [
{ id: 1, voteCount: "500 Votes" },
{ id: 2, voteCount: "200 Votes" },
{ id: 3, voteCount: "320 votes" }
]
};
render() {
const { data, contestantResult } = this.state;
return (
<div>
<h1> Electoral College Voting......</h1>
{data.map(person => {
const result = contestantResult.find(res => res.id === person.id);
return (
<Contestant
key={person.id}
data={person}
resultVotes={result.voteCount}
/>
);
})}
</div>
);
}
}
class Contestant extends React.Component {
render() {
return (
<div key={this.props.data.id}>
<div style={{ background: "black", color: "white" }}>
<b>Id:</b>
{this.props.data.id}
<br />
<b>Name:</b> {this.props.data.name}
<br />
<b style={{ color: "red" }}>Vote Count: {this.props.resultVotes}</b>
<br />
</div>
</div>
);
}
}
ReactDOM.render(<VoteResult />, document.getElementById("root"));
<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>
<div id="root"></div>

Resources