Problem is when i click on edit button, they fill the text inputs with the previously clicked info. when i check my store, the right object is placed into my editor object. so I don't know what's wrong
import React,{Component} from 'react';
import {get_contact, update_contact} from '../actions/';
import {connect} from 'react-redux';
class Edit extends Component {
constructor(props){
super(props);
this.state = {// constructor and initialization of my state
namex: '',
emailx: '',
phonex: '',
idx: ''
}
this.nameInput = React.createRef();
this.emailInput = React.createRef(); //creating references for inputs
this.phoneInput = React.createRef();
}
componentDidMount(){
let id_1 =this.props.location.id;
this.props.get_contact(id_1);
const {id,name, email, phone} = this.props.edits;
this.setState({
namex: name,
emailx: email, //fetching info from props
phonex: phone,
idx: id
})
}
submit_handler = (e) => {
e.preventDefault();
this.setState({
name: this.nameInput.current.value,
email: this.emailInput.current.value,// accessing input values
phone: this.phoneInput.current.value
})
// this.props.update_contact(this.state);
// this.setState({
// name: '',
// email: '',
// phone: '',
// id: ''
// }) console.log(this.state)
} render(){
const {id,namex, emailx, phonex} = this.state;
return (
<div>
<div className = "ml-20 mt-10 " style = {{width: '500px', marginLeft: '400px',marginTop: '80px'}}>
<h3 className="display-4 text-center">Edit Contacts </h3>
<form onSubmit = {this.submit_handler.bind(this)}>
<div className = "form-group">
<label htmlFor ="Names">Names</label>
<input className="form-control" type="text" name="name" defaultValue={namex} ref = {this.nameInput}/>
</div>
<div className = "form-group">
<label htmlFor="email">Email</label>
<input className="form-control" type="email" name="email" defaultValue={emailx} ref = {this.emailInput}/>
</div>
<div className = "form-group">
<label htmlFor="contact">Contact</label>
<input className="form-control" type="text" name="phone" defaultValue={phonex} ref = {this.phoneInput} />
</div>
<div className = "form-group">
<input className="btn btn-primary btn-block" type="submit" name="editor" value="Edit" />
</div>
</form>
</div>
</div>
) } } const mapStateToProps = (state) => ({ edits: state.Users.editor }) export default connect(mapStateToProps, {get_contact,update_contact})(Edit);
Related
I have a form set up with React Class Components. I want to take the values input by the user and send them to another file. These values will be parameters of an external function call. The values I can console these values declared as constants in the handleSubmit() function but do not know how to export them
import React, {Component} from 'react';
import "./styles.css";
class TokenForm extends React.Component {
constructor(props) {
super(props);
this.state = {
daoName: '',
tokenName: '',
tokenSymbol: '',
daoCap: '',
minEth: '',
maxEth: '',
mintRate: '1000'
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();
const dName = event.target.daoName.value;
const tName = event.target.tokenName.value;
const tSymbol = event.target.tokenSymbol.value;
const dCap = event.target.daoCap.value;
const mnEth = event.target.minEth.value;
const mxEth = event.target.maxEth.value;
const mRate = event.target.mintRate.value;
console.log(dName, tName, tSymbol, dCap, mnEth, mxEth, mRate)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h1>Mint DAO Token</h1>
<p>Customise your token variables below</p>
<input type="text" placeholder="DAO Name" name="daoName" value={this.state.daoName} onChange={this.handleInputChange}/>
<input type="text" placeholder="Token Name" name="tokenName" value={this.state.tokenName} onChange={this.handleInputChange}/>
<input type="text" placeholder="Symbol e.g. ABC" name="tokenSymbol" value={this.state.tokenSymbol} onChange={this.handleInputChange}/>
<input type="number" placeholder="DAO Max Capacity" name="daoCap" value={this.state.daoCap} onChange={this.handleInputChange}/>
<input type="number" placeholder="Minimum Investment Limit (ETH)" name="minEth" value={this.state.minEth} onChange={this.handleInputChange}/>
<input type="number" placeholder="Maximum Investment Limit (ETH)" name="maxEth" value={this.state.maxEth} onChange={this.handleInputChange}/>
<select name="mintRate" value={this.state.mintRate} onChange={this.handleInputChange}>
<option value="1000">1,000</option>
<option value="10000">10,000</option>
<option value="100000">100,000</option>
</select>
<button type="submit">SUBMIT</button>
</form>
);
}
}
export default TokenForm;
Making a CV creator and I've added a popup form for users to input data and then render to the page. I'm having a lot of trouble figuring out how to reopen the popup with already submitted data for editing however, been hours of googling and no closer to having any idea what to do
the main work code
import React, { Component } from "react";
import Popup from 'reactjs-popup';
import CreateItems from './CreateItems'
class Work extends Component {
constructor(props) {
super(props);
this.state = {
items: []
};
this.addItem = this.addItem.bind(this);
this.deleteItem = this.deleteItem.bind(this);
}
addItem(e) {
var newItem = {
title: this.title.value,
company: this.company.value,
location: this.location.value,
date: this.date.value,
description: this.description.value,
key: Date.now()
};
this.setState((prevState) => {
return {
items: prevState.items.concat(newItem)
};
});
this.title.value = "";
this.company.value = "";
this.location.value = "";
this.date.value = "";
this.description.value = "";
e.preventDefault();
}
deleteItem(key) {
var filteredItems = this.state.items.filter(function (item) {
return (item.key !== key);
});
this.setState({
items: filteredItems
});
}
render(){
return (
<div id = "work-container">
<h2>Experience:</h2>
<CreateItems entries = {this.state.items}
delete= {this.deleteItem}/>
<Popup trigger={<button> Add New</button>} modal nested>
{close => (
<form id = 'modal-container' onSubmit={this.addItem}>
<span id = 'modal-header'>Add work experience</span>
<div id = 'row'>
<div className = 'row-segment-left'>
<label htmlFor = "job-title">Job Title</label>
<input id = "job-title" type = "text" ref={(a) => this.title = a}></input>
</div>
<div className = "row-segment-right">
<label htmlFor ='job-company'>Company</label>
<input id = 'job-company' type= 'text' ref={(a) => this.company = a}></input>
</div>
</div>
<div id = 'row'>
<div className = 'row-segment-left'>
<label htmlFor = "job-location">Job Location</label>
<input id = "job-location" type = "text" ref={(a) => this.location = a}></input>
</div>
<div className = "row-segment-right">
<label htmlFor ='job-date'>Date of Employment</label>
<input id = 'job-date' type= 'text' ref={(a) => this.date = a}></input>
</div>
</div>
<div id ='bottom-row'>
<label htmlFor ='job-description'>Job Description</label>
<textarea id = 'job-description' rows = '5' placeholder = 'Describe your duties...'
ref={(a) => this.description = a}></textarea>
</div>
<div id = 'button-container'>
<button type = "submit" >Submit</button>
<button onClick={() => {
close();
}}>Cancel</button>
</div>
</form>
)}
</Popup>
</div>
)}};
export default Work;
The code for creating and adding the content
import React, { Component } from "react";
class CreateItems extends Component {
constructor(props) {
super(props);
this.createTasks = this.createTasks.bind(this);
}
delete(key) {
this.props.delete(key);
}
createTasks(item) {
return <div className = 'work-segment' key={item.key}>
<h3>{item.title}</h3>
<span>{item.company} / {item.location} / {item.date}</span>
<p>{item.description}</p>
<span>
<button>Edit</button>
<button onClick={() => this.delete(item.key)}>Delete</button>
</span>
</div>
}
render() {
var workEntries = this.props.entries;
var workItems = workEntries.map(this.createTasks);
return (
<div id = 'work-items'>
{workItems}
</div>
);
}
};
export default CreateItems;
I have one question. I created contact form in react and I want to collapsed only single contact, which was clicked. Toggle is method which should collapse it. And colapse is state. My problem is that when I click it affect all contact and all are collapsed. How can I improve it?
ContactBook.js
import React, { Component } from "react";
import Contact from "../Contact/Contact";
import "./ContactBook.css";
class ContactBook extends Component{
constructor(props){
super(props);
this.state = {
colapse :true,
contacts: [
{
id: 1,
name: 'Propulsion Academy',
address: 'Zurich',
avatar: 'propulsion-academy-logo.png'
},
{
id: 2,
name: 'Propulsion Academy',
address: 'Luzern',
avatar: 'propulsion-academy-logo.png'
},
{
id: 3,
name: 'Propulsion Academy',
address: 'Munich',
avatar: 'propulsion-academy-logo.png'
},
],
};
}
toggle=()=>{
const doesShow = this.state.colapse;
this.setState({colapse: !doesShow});
}
deleteContact=(contactIndex)=>{
//with slice method we create copy of an array
const contacts =this.state.contacts.slice();
contacts.splice(contactIndex, 1);
this.setState({contacts: contacts})
}
//get name from input
addName = e =>{
this.setState({
name: e.target.value,
})
}
//get address from input
addAddress = e =>{
this.setState({
address: e.target.value,
})
}
//update state on button click
handleSubmit = (e) =>{
e.preventDefault()
if(this.state.name && this.state.address) {
this.setState(state =>{
const newContact = {
id: Math.max(...state.contacts.map(c => c.id))+1,
name: this.state.name,
address: this.state.address,
}
return{
contacts:[...state.contacts, newContact]
}
})
}
}
render() {
return (
<div className="contactBook">
<form className ="addContact" >
<p>New Contact</p>
<label id="name"><p>Name</p><input type='text' id="name" onChange={this.addName}/></label>
<label id="address"><p>Address:</p><input type='text' id="address" onChange={this.addAddress} /></label>
<input type='file' name='file' />
<button type='submit' onClick= {this.handleSubmit}>SUBMIT</button>
</form>
<div className="contacts">
{this.state.contacts.map((contact, index) =>
< Contact key={contact.id} contact={contact} delete={()=>this.deleteContact(index)} colapse={this.state.colapse} toggle={this.toggle}/>)
}
</div>
</div>
);
}
};
export default ContactBook;
Contact.js
import React from "react";
import "./Contact.css";
import avatar from '../assets/user.png'
const Contact = (props) =>{
return (
<div className = "col" >
<img src={avatar} alt="avatar" onClick={props.toggle}/>
{props.colapse === true ?
<div>
<p>Name: {props.contact.name}</p>
<p>Address: {props.contact.address}</p>
<button onClick={props.delete}> Delete </button>
</div> : null
}
</div>
)
};
export default Contact;
I recommend to you to move the collapse and his method to the Contact component it self like this :
const Contact = (props) =>{
[collapse,setCollapse] = useState(true)
return (
<div className = "col" >
<img src={avatar} alt="avatar" onClick{()=>setCollape(prev=>!prev)}/>
{collapse === true ?
<div>
<p>Name: {props.contact.name}</p>
<p>Address: {props.contact.address}</p>
<button onClick={props.delete}> Delete </button>
</div> : null
}
</div>
)
};
In this component I created a state that will manage the collapse for each of the component the render in the map.
further more, the prev give you the last value you submit and it's best practice to use the prev instead of just setCollapse(!collapse)
You have one function for all contacts, and since you use .map() they will all behave the same, since toggling one toggles the state which is used to render all individual contacts. The solution would be to pass the selected contact in your state so your app actually knows which one is to be rendered! Hopefully that makes sense!
Good luck and let us know how things work out!
This is it:
ContactBook.js
import React, { Component } from "react";
import Contact from "./Contact";
// import "./ContactBook.css";
class ContactBook extends Component {
constructor(props) {
super(props);
this.state = {
contacts: [
{
id: 1,
name: "Propulsion Academy",
address: "Zurich",
avatar: "propulsion-academy-logo.png",
colapse: true
},
{
id: 2,
name: "Propulsion Academy",
address: "Luzern",
avatar: "propulsion-academy-logo.png",
colapse: true
},
{
id: 3,
name: "Propulsion Academy",
address: "Munich",
avatar: "propulsion-academy-logo.png",
colapse: true
}
]
};
}
// toggle = () => {
// const doesShow = this.state.colapse;
// this.setState({ colapse: !doesShow });
// };
deleteContact = contactIndex => {
//with slice method we create copy of an array
const contacts = this.state.contacts.slice();
contacts.splice(contactIndex, 1);
this.setState({ contacts: contacts });
};
togglecontact = contactIndex => {
let contacts = this.state.contacts.slice();
contacts[contactIndex].colapse = !contacts[contactIndex].colapse;
this.setState({ contacts: contacts });
};
//get name from input
addName = e => {
this.setState({
name: e.target.value
});
};
//get address from input
addAddress = e => {
this.setState({
address: e.target.value
});
};
//update state on button click
handleSubmit = e => {
e.preventDefault();
if (this.state.name && this.state.address) {
this.setState(state => {
const newContact = {
id: Math.max(...state.contacts.map(c => c.id)) + 1,
name: this.state.name,
address: this.state.address
};
return {
contacts: [...state.contacts, newContact]
};
});
}
};
render() {
return (
<div className="contactBook">
<form className="addContact">
<p>New Contact</p>
<label id="name">
<p>Name</p>
<input type="text" id="name" onChange={this.addName} />
</label>
<label id="address">
<p>Address:</p>
<input type="text" id="address" onChange={this.addAddress} />
</label>
<input type="file" name="file" />
<button type="submit" onClick={this.handleSubmit}>
SUBMIT
</button>
</form>
<div className="contacts">
{this.state.contacts.map((contact, index) => (
<Contact
key={contact.id}
contact={contact}
togglecontact={() => this.togglecontact(index)}
delete={() => this.deleteContact(index)}
colapse={this.state.colapse}
toggle={this.toggle}
/>
))}
</div>
</div>
);
}
}
export default ContactBook;
contactbook.js
import React from "react";
// import "./Contact.css";
const Contact = props => {
let buffer;
props.contact.colapse === true
? (buffer = (
<div>
<p>Name: {props.contact.name}</p>
<p>Address: {props.contact.address}</p>
<button onClick={props.delete}> Delete </button>
</div>
))
: null;
return (
<div className="col">
<img
onClick={props.togglecontact}
src="data:image/jpeg;base64,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"
/>
{buffer}
</div>
);
};
export default Contact;
can check it at:https://stackblitz.com/edit/react-mrvrr1?file=src%2FContact.js
only Toggling single element.
App not behaving correctly when I try signing up along with posting Stripe payment, it will not push the sashboard component
The error I am getting:
Unhandled Rejection (TypeError): Cannot read property 'push' of undefined
handleStripeSubmit
src/components/sections/SignupForm.js:78
75 | const { id } = paymentMethod;
76 | console.log("111111111 and ID_", id);
77 | aprops.signup(state, id);
78 | aprops.history.push("/dashboard");
| ^ 79 |
80 | console.log("3333333333");
81 | // setState({ ...state, stripeId: id });
My Code (what do youthink is not working?:
someone, please help...
import React, { useState } from "react";
import classNames from "classnames";
import { Link, withRouter, Route } from "react-router-dom";
import SectionHeader from "./partials/SectionHeader";
import Input from "../elements/Input";
import Button from "../elements/Button";
import { signupUser } from "../../redux/actions/user_action";
import { CardElement, useStripe, useElements } from "#stripe/react-stripe-js";
import { connect } from "react-redux";
import { createHashHistory } from 'history';
export const history = createHashHistory()
//Checkout Form component-----------------------------------------------=
const StripeForm = (aprops) => {
const [state, setState] = useState({
bname: "Busines Name",
email: "Email address",
password: "Password",
name: "Name on Card",
amount: 0,
plan: "",
stripeId: "",
});
const {
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
...props
} = aprops;
const outerClasses = classNames(
"signin section",
topOuterDivider && "has-top-divider",
bottomOuterDivider && "has-bottom-divider",
hasBgColor && "has-bg-color",
invertColor && "invert-color",
className
);
const innerClasses = classNames(
"signin-inner section-inner",
topDivider && "has-top-divider",
bottomDivider && "has-bottom-divider"
);
const sectionHeader = {
title: "Welcome. We exist to make cybersecurity easier.",
};
const handlechangeall = (event) => {
setState({ ...state, [event.target.name]: event.target.value });
};
const handleRadio = (e) => {
setState({
...state,
amount: Number(e.target.value) * 100,
plan: e.target.id,
});
};
const handleStripeSubmit = async () => {
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement),
});
if (!error) {
console.log("response of stripe payment___", paymentMethod);
const { id } = paymentMethod;
console.log("111111111 and ID_", id);
aprops.signup(state, id);
aprops.history.push("/dashboard");
console.log("3333333333");
// setState({ ...state, stripeId: id });
}
};
const handlesubmit = (event) => {
event.preventDefault();
handleStripeSubmit();
//alert( JSON.stringify(this.state));
console.log(JSON.stringify(state));
};
//Stripe hooks-------
const stripe = useStripe();
const elements = useElements();
//=============================
return (
<section {...aprops} className={outerClasses}>
<div className="container">
<div className={innerClasses}>
<SectionHeader
tag="h1"
data={sectionHeader}
className="center-content"
/>
<div className="tiles-wrap">
<div className="tiles-item">
<div className="tiles-item-inner">
<form onSubmit={handlesubmit}>
<fieldset>
<div className="mb-12">
<Input
label="Business name"
type="text"
name="bname"
value={state.bname}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div className="mb-12">
<Input
type="email"
name="email"
label="Email"
value={state.email}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div className="mb-12">
<Input
type="password"
name="password"
label="Password"
value={state.password}
onChange={handlechangeall}
labelHidden
required
/>
</div>
{/* Stripe Integration */}
<div className="signin-bottom has-top-divider">
<div className="pt-32 text-xs center-content text-color-low">
Select Subscription tier (to select, use up & down arrow
keys):
</div>
</div>
{/* all packages amounts here */}
<div onChange={handleRadio} className="radio">
{console.log("checking plan amount____", state.amount)}
<div>
<label>
<input
type="radio"
id="default"
value="49"
name="plan"
/>
($49/month)
</label>
</div>
<div>
<label>
<input
type="radio"
id="basic"
name="plan"
value="199"
/>
Basic ($199/month)
</label>
</div>
<div>
<label>
<input
type="radio"
id="complete"
name="plan"
value="249"
/>
Complete ($249/month)
</label>
</div>
</div>
<div className="pt-32 text-xs center-content text-color-low">
Enter Card Details Here!
<div className="mb-12">
<Input
label="Name on the card"
type="text"
name="name"
value={state.name}
onChange={handlechangeall}
labelHidden
required
/>
</div>
<div
style={{
border: "1px solid grey",
padding: 15,
backgroundColor: "#cccccc",
}}
>
<CardElement />
</div>
{/* <button type="submit" disabled={!stripe}>
Checkout
</button> */}
<div className="mt-24 mb-32">
<Button type="submit" color="primary" wide>
Register
</Button>
</div>
</div>
</fieldset>
</form>
<div className="signin-bottom has-top-divider">
<div className="pt-32 text-xs center-content text-color-low">
Already have an account?{" "}
<Link to="/login/" className="func-link">
Login
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
);
};
// const SignupForm = () => {
// return (
// <Elements stripe={stripePromise}>
// <StripeForm />
// </Elements>
// );
// };
// SignupForm.propTypes = propTypes;
// SignupForm.defaultProps = defaultProps;
const mapStateToProps = (state) => ({});
const mapDispatchToProps = (dispatch) => {
return { signup: (data, id) => dispatch(signupUser(data, id)) };
};
export default connect(mapStateToProps, mapDispatchToProps)(StripeForm);
You are not passing history prop to StripeForm component - it is undefined. what is actually passed is { signup: (data, id) => dispatch(signupUser(data, id)) }.
A possible solution could be:
const mapStateToProps = (state) => ({ history: [] });
or assigning history some default value:
const {
className,
topOuterDivider,
bottomOuterDivider,
topDivider,
bottomDivider,
hasBgColor,
invertColor,
history = [],
...props
} = aprops;
In my code, I use a click event on the InterestBox in order to update the appearance of the InterestBox and to change the state of the parent of the parent of InterestBox.
However, when I inspect the element with the React Developer Tools or that I try to send a request to my API, the state.interests is always empty. But, when I log the state in the console, it shows an array with a length of 0, but containing all the proper values.
I tried to find what is wrong with my code, but I think I need an external look to find what is wrong.
import axios from 'axios';
import * as Cookies from 'js-cookie';
import React, { Component } from 'react';
import Button from '../../components/Button';
import Dashboard from '../Dashboard';
import ErrorContainer from '../../components/ErrorContainer';
import InterestList from '../../components/register/InterestList';
export class EditUser extends Component {
constructor(props) {
super(props);
this.state = {loading: true, interests: []}
this.addInterest = this.addInterest.bind(this);
this.logState = this.logState.bind(this);
}
addInterest(id, name) {
console.log('hoppity hippity you parenty')
var mid = 'm' + id;
console.log(this.state.interests[mid] == undefined)
if(this.state.interests[mid] == undefined) {
console.log(this.state);
this.setState((state) => {
state.interests[mid] = name;
return {interests: state.interests}
}, () => {
console.log(JSON.stringify(this.state.interests))
})
} else {
console.log('deleted')
var newInterest = this.state.interests;
delete newInterest[mid]
this.setState({interests: newInterest})
}
console.log(this.state.interests)
}
componentDidMount() {
var token = Cookies.get('token');
axios.get('http://localhost:8000/api/details', {headers: {"Accept": 'application/json', "Authorization": `Bearer ${token}`}}).then(
(success) => {
this.setState({
loading: false,
firstname : success.data.data.user.firstname,
lastname: success.data.data.user.lastname,
email: success.data.data.user.email,
dob: success.data.data.user.dob,
address: success.data.data.user.address,
uinterests: success.data.data.interests
})
}, (error) => {
this.props.history.push('/deconnexion');
}
)
var places = require('places.js');
var placesAutocomplete = places({
appId: "plZJLSHIW8M5",
apiKey: "0eddd2fc93b5429f5012ee49bcf8807a",
container: document.querySelector('#address-input')
});
}
logState() {
console.log(this.state);
}
render() {
return (
<Dashboard loading={this.state.loading}>
<h1 className="title">Modifier mon profil</h1>
<form className="user-form offer-update-form" onSubmit={this.handleSubmit}>
<label>Prénom :</label>
<input type="text" name="firstname" value={this.state.firstname} onChange={this.handleChange}></input> <br />
<label>Nom de famille :</label>
<input type="text" name="lastname" value={this.state.lastname} onChange={this.handleChange}></input> <br />
<label>Email :</label>
<input type="email" name="email" value={this.state.email} onChange={this.handleChange} /><br />
<label>Adresse :</label>
<input type="address" id="address-input" name="address" value={this.state.address} onChange={this.handleChange} /><br />
<label>Date de naissance :</label>
<input type="date" name="dob" value={this.state.dob} onChange={this.handleChange} /><br />
<InterestList alreadyChecked={this.state.uinterests} onClick={this.addInterest} />
<ErrorContainer errors={this.state.errors} />
<Button type="primary">Soumettre les changements</Button>
</form>
<Button type="danger" onClick={this.logState} />
</Dashboard>
)
}
}
export default EditUser
```
```
import React, { Component } from 'react'
import InterestBox from './InterestBox'
import Axios from 'axios'
export class InterestList extends Component {
constructor(props) {
super(props);
this.state = {pinterests: []}
this.pinterestRefs = React.createRef()
this.pinterestRefs.current = [];
}
componentDidMount() {
Axios.get('http://localhost:8000/api/interests')
.then((success) => {
this.setState({pinterests: success.data.data.interests});
})
}
componentDidUpdate(prevProps) {
console.log(JSON.stringify(prevProps));
console.log(JSON.stringify(this.props))
if(this.props.alreadyChecked != prevProps.alreadyChecked) {
this.props.alreadyChecked.forEach((item) => {
this.pinterestRefs.current.forEach((pinterest) => {
if(item == pinterest.props.id) {
console.log(pinterest)
pinterest.handleClick();
}
})
console.log(item)
})
}
console.log(this.pin)
}
render() {
return (
<React.Fragment>
{Object.keys(this.state.pinterests).map((interest, i) => {
var pinterest = this.state.pinterests[interest];
var callbackRef = node => this.pinterestRefs.current[i] = node;
return <InterestBox id={pinterest.id} onClick={this.props.onClick} icon={pinterest.picture_src} title={pinterest.name} ref={callbackRef} />
})}
</React.Fragment>
)
}
}
export default InterestList
```
```
import React, { Component } from 'react'
export class InterestBox extends Component {
constructor(props) {
super(props);
this.images = require('../../img/interests/*.svg');
this.state = {activated: false};
this.interest_box_content = React.createRef();
this.interest_text = React.createRef();
this.handleClick = this.handleClick.bind(this);
this.updateDimensions = this.updateDimensions.bind(this);
}
handleClick() {
console.log('hoppity hippity you clicky')
this.props.onClick(this.props.id, this.props.title);
this.setState(prevState => ({
activated: !prevState.activated
}))
}
updateDimensions() {
console.log((window.getComputedStyle(this.refs.interest_box_content).width))
this.refs.interest_text = (window.getComputedStyle(this.refs.interest_box_content).width)
}
render() {
return (
<div className="column is-one-fifth-desktop is-half-touch">
<div className="interest-box">
<div className="interest-box-adjuster">
<div ref={"interest_box_content"} className={"interest-box-content " + (this.state.activated == true ? 'interest-box-activated' : '')} onClick={this.handleClick}>
<img className="interest-icon" src={this.images[this.props.icon]} style={{'height': '50%'}}></img>
<i className="activated-icon fas fa-check"></i>
<span ref={"interest_text"} className="interest-text">{this.props.title}</span>
</div>
</div>
</div>
</div>
)
}
}
export default InterestBox
```
you have initialized interest as an array using []
but then, you are updating it as a map state.interests[mid] = name;
Note: JS is not type-safe. after the above statement, interests no longer remained an array
That's the reason why on console you are able to see it being populated but with an array length of 0. that's because you are outputting an object now and not an array.