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
Related
I'm working on a portfolio site and I want to have 2 buttons, 1 for "print" and 1 for "digital".
In react I have all my projects set up in a array of objects file called "ProjectsList".
How can I make it so when I click on a button, it filters the items in my array map and only displays the ones with the same 'category' value?
At the moment I can only get it so when I click the buttons it returns them all as "true" but can't get it to change the actual state of an object item to false if it doesn't match the button's id that I clicked.
index.jsx file:
import React, { useState } from "react"
import Seo from "../../components/seo"
import ProjectItem from "./ProjectItem";
export default function ProjectsPage() {
const [active, setActive] = useState();
return (
<>
<Seo title="Home" />
<div className="container">
<ProjectItem />
</div>
</>
)
}
ProjectItem.jsx file:
import React, { useState } from "react"
import { Link } from "gatsby"
import { ProjectsList } from "./data";
export default function ProjectItem() {
const [active, setActive] = useState();
function getCategories(e) {
{ProjectsList.map((item, i) => {
if (e.target.id == item.category) {
setActive(true)
}
else {
setActive(false)
}
})
}
}
return (
<>
<h2>Projects</h2>
<div className="double-buttons spacer-4">
<button className="button" id="print" onClick={(e) => getCategories(e)}>
Print Button
</button>
<button className="button" id="digital" onClick={(e) => getCategories(e)}>
Digital Button
</button>
</div>
<div className="grid--col-4" id="projectsSection">
{
ProjectsList.map((item, i) => {
return (
<Link
to={item.path}
className={active ? 'project-tile active' : 'project-tile hidden'}
key={i}>
<div className="grid__cell">
<img src={item.backgroundUrl} alt={item.title} />
<div className="grid__cell__title">
<h4>{item.title}</h4>
</div>
</div>
</Link>
)
}
)
}
</div>
</>
)
}
data.js array file:
export const ProjectsList = [
{
title: 'Project 1',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'print',
active: true
},
{
title: 'Project 2',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'digital',
active: true
},
{
title: 'Project 3',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'print',
active: true
},
{
title: 'Project 4',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'digital',
active: true
},
]
You need to make a state for the projectList so that when you change any of the data it's saved and then rendered with the new value. In your case each time It re-renders it returns the original data from the file. So I just to make something like this.
const [projectList, setProjectList] = useState([
{
title: 'Project 1',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'print',
active: true
},
{
title: 'Project 2',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'digital',
active: true
},
{
title: 'Project 3',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'print',
active: true
},
{
title: 'Project 4',
backgroundUrl: 'backgroundUrl',
path: '#',
category: 'digital',
active: true
},
])
So when you click digital or print button the onClick function will be something like this
const getCategories = useCallback(()=>{
const newProjectList = [...projectList]
newProjectsList.map((item, i) => {
if (e.target.id == item.category) {
item.active = true
}
else {
item.active = false
}
})
setProjectList(newProjectList)
},[projectList, setProjectList])
I replaced the active state because it is useless as it is not connected to each project. So I changed each project status in the main object from true to false based on which button is clicked.
You need also to modify this to read the state of each project.
{
ProjectsList.map((item, i) => {
return (
<Link
to={item.path}
className={item.active ? 'project-tile active' : 'project-tile hidden'}
key={i}>
<div className="grid__cell">
<img src={item.backgroundUrl} alt={item.title} />
<div className="grid__cell__title">
<h4>{item.title}</h4>
</div>
</div>
</Link>
)
}
)
}
I'm new to react and trying to create a menu bar of sorts. All the similar questions seem to be older or not quite what I need. Regardless, I can't get this to work so please help figuring this out.
I'm using react-icons and would like to dynamically name the component so I can use the icons within this loop but <{val.icon} /> is throwing an error: "'...' expected." What can I do to make this work? I also can't seem to declare variables in a return statement to work around this, or at least I can't figure out how to do so. Any idea?
const values = [
{ id: 1, text: "Home", icon: "MdHomeFilled" },
{ id: 2, text: "Schedule", icon: "MdEditCalendar" },
{ id: 3, text: "Scores", icon: "MdSportsTennis" },
{ id: 4, text: "Stats", icon: "IoIosStats" }
];
return (
<>
<ul>
{values.map((val) => (
<li onClick={() => setActiveId(val.id)}>
<div className={activeId === val.id ? "NavLinkBox selected":"NavLinkBox"}>
<div className="navLinkBoxHdr"><{val.icon} /></div>
<div className="navLinkBoxCnt">{val.text}</div>
</div>
</li>
))}
</ul>
You can't just use a component name (i.e. as a string) in order to render a component.
In order to render it, you need to import it like you would regularly, then convert it into a variable with a capitalized name. For example:
import MdHomeFilled from './MdHomeFilled';
import MdEditCalendar from './MdEditCalendar';
export default function App() {
const values = [
{ id: 1, text: "Home", icon: MdHomeFilled },
{ id: 2, text: "Schedule", icon: MdEditCalendar }
];
return (
<ul>
{values.map((val) => {
const IconComponent = val.icon; // This way you can use this field as a component
return (
<li key={val.id} onClick={() => setActiveId(val.id)}>
<div className={activeId === val.id ? "NavLinkBox selected":"NavLinkBox"}>
<div className="navLinkBoxHdr"><IconComponent /></div>
<div className="navLinkBoxCnt">{val.text}</div>
</div>
</li>
);
})}
</ul>
);
}
I'm trying to map out an array of objects in react but I'm stuck trying to map each entry.
const activities = [
{ value: "uniqueValue1", title: "Dancing", label: "Cha cha slide" },
{ value: "uniqueValue2", title: "Dancing", label: "Doing the salsa" },
{ value: "uniqueValue3", title: "Swimming", label: "Back stroke" },
{ value: "uniqueValue4", title: "Swimming", label: "Diving in the pool" },
{ value: "uniqueValue5", title: "Playing", label: "With toys" },
{ value: "uniqueValue6", title: "Playing", label: "With friends" },
]
and i'm looking to map each out into a checkbox to be selected:
<ul>
{activityOptions.map(({ title, label }, index) => {
return (
<p key={index}>
<div>
<div>
<input
type="checkbox"
id={`custom-checkbox-${index}`}
name={label}
value={label}
class="form-check-input"
defaultValue={settingState.activity}
onChange={(value) => {
setSettingState({...settingState, ...{ activity: value }});
}}
options={activityOptions}
isDisabled={settingState.company}
/>
<h6 htmlFor={`custom-checkbox-${index}`}>{type}</h6>
<label htmlFor={`custom-checkbox-${index}`}>{label}</label>
</div>
</div>
</p>
);
})}
</ul>
how would I get it map collective titles rather than printing one per line?
Dancing: <--- h6 maybe
cha cha sldide <--- checkbox
doing the salsa
Swimming:
Back stroke
Diving in the pool
etc...
Rather than
Dancing:
cha cha slide
Dancing:
doing the salsa
Swimming:
Back stroke
Swimming:
Diving in the pool
etc...
This is how you can do it
const activities = [
{ value: "uniqueValue1", title: "Dancing", label: "Cha cha slide" },
{ value: "uniqueValue2", title: "Dancing", label: "Doing the salsa" },
{ value: "uniqueValue3", title: "Swimming", label: "Back stroke" },
{ value: "uniqueValue4", title: "Swimming", label: "Diving in the pool" },
{ value: "uniqueValue5", title: "Playing", label: "With toys" },
{ value: "uniqueValue6", title: "Playing", label: "With friends" }
];
const activityOptions = {};
activities.forEach(({ value, title, label }) => {
let option = activityOptions[title];
if (option) {
activityOptions[title] = [...activityOptions[title], { value, label }];
} else {
activityOptions[title] = [{ value, label }];
}
});
return (
<ul>
{Object.keys(activityOptions).map((id, index) => {
const options = activityOptions[id];
return (
<li>
<p key={index}>{id}</p>
{options.map(({ type, label }) => (
<div>
<input
type="checkbox"
id={`custom-checkbox-${index}`}
name={id}
value={id}
class="form-check-input"
defaultValue={settingState.activity}
onChange={(value) => {
setSettingState({...settingState, ...{ activity: value }});
}}
options={options}
/>
<label htmlFor={`custom-checkbox-${index}`}>{label}</label>
</div>
))}
</li>
);
})}
</ul>
);
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>
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>