How to access variables outside of map function? - reactjs

Have looped over some data in my applicaition but I was wondering if I could access variables outside the map function?
I am trying to read a count of my data, however the object.unit_test_count(which is shown in asteriks) is coming back as object is not defined? How do I access that unit_test_count from the objectsToShow.map function? (also shown in asteriks)
<div className={getGridClassName()} style={{backgroundColor: 'var(--main-color)', color: '#fff', fontWeight: '500'}}>
<div />
**<div>Object{object.unit_test_count}</div>**
<div />
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}># Unit Tests</div>
<div style={{textAlign: 'center'}}>Select</div>
</React.Fragment>
:
<React.Fragment>
<div style={{textAlign: 'center'}}>Passes</div>
<div style={{textAlign: 'center'}}>Fails</div>
<div style={{textAlign: 'center'}}>
<Tooltip title={'hello'}>Errors<InfoIcon/>
</Tooltip>
</div>
<div style={{textAlign: 'center'}}>N/A<InfoIcon /></div>
<div style={{textAlign: 'center'}}># Units Tests</div>
</React.Fragment>
}
</div>
{!objectsToShow ? null : **objectsToShow.map(object =>**
<div key={object.object} className={getGridClassName(object)}>
<div style={{display: 'flex', justifyContent: 'flex-end'}}>
<Tooltip title={object.relation.charAt(0).toUpperCase() + object.relation.substr(1).toLowerCase()}>
<div className='RelationInitialBox' style={{backgroundColor: getRelationColor(object.relation)}}>
{object.relation.charAt(0).toUpperCase()}
</div>
</Tooltip>
</div>
<div
className='ClickableText'
style={{wordBreak: 'break-all'}}
onClick={() => onObjectClick(object.object)}
>
{object.object}
</div>
<div>{object.is_critical ? 'Critical' : ''}</div>
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
<div style={{textAlign: 'center'}}>
<Checkbox mainColor changeHandler={props.handleObjectsCheckbox} data={object} />
</div>
</React.Fragment>
:
<React.Fragment>
<div style={{color: 'green', textAlign: 'center'}}>{object.unit_test_passes}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_fails}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_errors}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_not_applicable}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
</React.Fragment>
}
</div>
)}
Update syntax error:
Syntax error image
objectsToShow.map(item =>
<div className='Card' style={{overflow: 'visible'}}>
<div className={getGridClassName()} style={{backgroundColor: 'var(--main-color)', color: '#fff', fontWeight: '500'}}>
<div />
<div>Object{item.unit_test_count}</div>
<div />
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}># Unit Tests</div>
<div style={{textAlign: 'center'}}>Select</div>
</React.Fragment>
:
<React.Fragment>
<div style={{textAlign: 'center'}}>Passes</div>
<div style={{textAlign: 'center'}}>Fails</div>
<div style={{textAlign: 'center'}}>
<Tooltip title={'hello'}>Errors<InfoIcon/>
</Tooltip>
</div>
<div style={{textAlign: 'center'}}>N/A<InfoIcon /></div>
<div style={{textAlign: 'center'}}># Units Tests</div>
</React.Fragment>
}
</div>
)
{!objectsToShow ? null : objectsToShow.map(object =>
<div key={object.object} className={getGridClassName(object)}>
<div style={{display: 'flex', justifyContent: 'flex-end'}}>
<Tooltip title={object.relation.charAt(0).toUpperCase() + object.relation.substr(1).toLowerCase()}>
<div className='RelationInitialBox' style={{backgroundColor: getRelationColor(object.relation)}}>
{object.relation.charAt(0).toUpperCase()}
</div>
</Tooltip>
</div>
<div
className='ClickableText'
style={{wordBreak: 'break-all'}}
onClick={() => onObjectClick(object.object)}
>
{object.object}
</div>
<div>{object.is_critical ? 'Critical' : ''}</div>
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
<div style={{textAlign: 'center'}}>
<Checkbox mainColor changeHandler={props.handleObjectsCheckbox} data={object} />
</div>
</React.Fragment>
:
<React.Fragment>
<div style={{color: 'green', textAlign: 'center'}}>{object.unit_test_passes}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_fails}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_errors}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_not_applicable}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
</React.Fragment>
}
</div>
)}
<PageNumbers pageNumbersList={pageNumbers} currentPage={currentPage} onClick={onPageNumberClick} />
</div>
)
})
objectsView.propTypes = {
objects: PropTypes.array,
status: PropTypes.oneOf(['', 'Failed', 'Success', 'Unresolved']),
onObjectClick: PropTypes.func,
handleObjectsCheckbox: PropTypes.func
}
export default withRouter(objectsView)

In this below line,
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
map() will check for the property on the variable name you passed to map at
{!objectsToShow ? null : **objectsToShow.map(object =>**
So you can change that variable name to something else.
Or
You can assign object.unit_test_count to any other variable and use it inside the loop.

Related

How to close only one Div at a time in React?

Code:-
const [Close, setClose] = useState(true)
<div className="allDivs">
{item.map((item, index) => {
// console.log("myDivs", myDivs);
return (
<Fragment key={index} >
<div className="tableHeaderBody" id="CLOSEDIV" style={{display: Close ? 'initial' : 'none'}}>
<div className="TableText">
<div className="TableTextHide"></div> <div style={{ color: "white" }} id="SHOW">{item.val}</div></div>
<div className="CloseIcon" id="CloseBtn"><FaCircle style={{ color: "#FC0000", width: "10px", height: "10px", alignItems: "right" }} onClick={() => setClose(false)} /></div>
</div>
</Fragment>
)
})
}
</div>
I want that when i click the Red circle at any div (show in image) it close the div, but right now when i click the One div red circle its closes all the div
please help.
Try this:
Create a new component ChildComponent:
export default function ChildComponent({item}) {
const [Close, setClose] = useState(true) // Every Child now has it's own setClose controll
return (
<Fragment>
<div className="tableHeaderBody" id="CLOSEDIV" style={{display: Close ? 'initial' : 'none'}}>
<div className="TableText">
<div className="TableTextHide"></div>
<div style={{ color: "white" }} id="SHOW">{item.val}</div>
</div>
<div className="CloseIcon" id="CloseBtn">
<FaCircle style={{ color: "#FC0000", width: "10px", height: "10px", alignItems: "right" }} onClick={() => setClose(false)} />
</div>
</div>
</Fragment>
)
}
Pass the ChildComponent to your component shown above:
<div className="allDivs">
{item.map((item, index) => (
<div key={index}>
<ChildComponent item={item} />
</div>
))}
</div>

How to use ternary operator inside map

I am trying to use a ternary operator inside a map, but not to sure why this is wrong? Getting a parsing error at the end of the ternary
code:
return(
<div className='Card'>
<div className='TableTopbar ScheduleGrid'>
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule)=>
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}
)
)
export default scheduleRowTwo
Updated code:
return(
<div className='Card'>
<div className='TableTopbar ScheduleGrid'>
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule)=>
(
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}
)
)
export default scheduleRowTwo
Updated error:
Apparently, your outermost div does not have a closing tag, thus resulting in an error.
Also, you're missing a return statement.
return (
<div className="Card">
<div className="TableTopbar ScheduleGrid">
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule) => {
return UsageMode === "Read" ? (
<div className="Table ScheduleGrid">
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{
padding: "2px",
width: "0.8em",
height: "0.8em",
marginRight: "5px",
}}
className="CircleButton"
onClick={onEditScheduleClick}
/>
</div>
</div>
) : (
<div>ID</div>
);
})}
</div>
);
Try this code. Should work.
You should enclose this code block with parentheses because you're trying to implicitly return an object (without the return keyword):
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}

how to change the value using setsate in Select tag if the number of select tag is changeable

I am new in react and I am using select tag to select answers to questions and this select tag changes based on the number of questions which can modify too ..
I want to save the selection of each answer with its question .. I hope someone can help me in this :
<Card>
<Card.Header>
<Card.Title as='h5'>
Select questions and their answer to create the decision tree
</Card.Title>
</Card.Header>
<Card.Body>
{ Object.entries(this.state.liste).map(([ke,values]) => {
return (
<div className="row ">
<div className="col-xl-11">
<h6 className="align-items-center float-left">{ke}</h6>
<div className="progress-bar progress-c-theme" role="progressbar" style={{width: '0%'}} aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"/>
<div className="text-right">
<div className="col-md-11" style={{ width: '130px', height: '20px', top: '-20px', right: '-400px' }}>
<select name = "secondSelectt" onChange={this.handleChange}>
{Object.values(values).map(key=>{
return (
<option id={key}>{key}</option>
);
})}
</select>
</div>
</div>
<div className="progress m-t-30 m-b-20" style={{height: '1px'}}>
<div className="progress-bar progress-c-theme" role="progressbar" style={{width: '0%'}} aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"/>
</div>
</div>
</div>
)})
}
</Card.Body>
</Card>
You need to add value to your options. And a default value to your select. that will come from your states. (handleChange) will update this state.
this.state = {
secondSelectt: '',
liste: [1,2,3,4,5],
}
handleChange({target: { name, value }}) {
this.setState({
[name]: value
});
}
Your new code.
<Card>
<Card.Header>
<Card.Title as='h5'>Select questions and their answer to create the decision tree</Card.Title>
</Card.Header>
<Card.Body>
{this.state.liste.map(number => {
return (
<div className="row ">
<div className="col-xl-11">
<h6 className="align-items-center float-left">{ke}</h6>
<div className="progress-bar progress-c-theme" role="progressbar"
style={{ width: '0%' }} aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" />
<div className="text-right">
<div className="col-md-11" style={{ width: '130px', height: '20px', top: '-20px', right: '-400px' }}>
<select name="secondSelectt" value={this.state.selectedValue} onChange={(event) => this.handleChange(event)}>
{Object.values(values).map(key => { return (<option key={key} value={key}>{key}</option>) })}
</select>
</div>
</div>
<div className="progress m-t-30 m-b-20" style={{ height: '1px' }}>
<div className="progress-bar progress-c-theme" role="progressbar"
style={{ width: '0%' }} aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" />
</div>
</div>
</div>)
})
}
</Card.Body>
</Card>
This is the specific change I've made.
this.state = {
liste: [1,2,3,4,5]
}
<select
name="secondSelectt"
value={this.state.selectedValue}
onChange={(event) => this.handleChange(event)}
>
{liste.map(number => <option key={number} value={number}>{number}</option>)}
</select>

Is there a way to force a React component to rerender a child?

I have a React component <ProductPrices>:
render() {
if (this.props.currentProduct.id !== 'new' && !this.props.currentProductPrices) {
this.props.fetchProductPrices(this.props.currentProduct.id);
}
return (
<div>
<div style={{backgroundColor: 'gray', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<h1>Precios</h1>
</div>
<div>
{this.props.currentProductPrices && this.props.currentProductPrices.map((price, index) => {
console.log({detail: price});
return (
<ProductPricesEntry key={price.id} price={price} index={index} />
)
})}
</div>
</div>
)
}
As you can see, <ProductPrices> contains a number of subcomponents <ProductPricesEntry>, which amount is dynamic depending on Redux state variable currentProductPrices:
render() {
console.log({entry: this.props.price});
return (
<div style={{display: 'flex', background: 'white', backgroundColor: 'lightgray', marginTop: '2px', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<div className='col-10'>
<div fullWidth>
<h3>{this.props.price.prices_table.name}</h3>
</div>
<div fullWidth style={{display: 'flex'}}>
{this.props.price.current_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.props.price.current_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.props.price.due_date?
<div style={{textAlign: 'center'}} className='col-4'><strong>{this.props.price.due_date}</strong></div>:
<div style={{textAlign: 'center', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.props.price.next_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.props.price.next_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
</div>
<div fullWidth style={{display: 'flex'}}>
<div style={{textAlign: 'right'}} className='col-4'>Actual</div>
<div style={{textAlign: 'center'}} className='col-4'>Vigencia</div>
<div style={{textAlign: 'right'}} className='col-4'>Próximo</div>
</div>
</div>
<div className='col-1'>
<IconButton color="primary" aria-label={''.concat('update-price-', this.props.price.id)}>
<i className="zmdi zmdi-edit zmdi-hc-fw" onClick={this.handleUpdateClick} />
</IconButton>
<Dialog fullWidth open={this.state.updateDialogOpen} arialabelledby={''.concat('update-price-', this.props.price.id)}>
<DialogTitle id={"".concat("update-price-", this.props.price.id)}>Actualizar Precio</DialogTitle>
<DialogContentText>
<div style={{paddingLeft: '25px'}}><h2>{this.props.currentProductData.name}</h2></div>
<div style={{paddingLeft: '25px'}}><h2>{this.props.price.prices_table.name}</h2></div>
</DialogContentText>
<DialogContent>
<FormControl fullWidth>
<InputLabel htmlFor="newPrice">Precio</InputLabel>
<Input
type="number"
id="newPrice"
name="newPrice"
value={this.state.newPrice}
onChange={this.handleChange}
startAdornment={<InputAdornment position="start">$</InputAdornment>}
/>
</FormControl>
<div fullWidth><TextField fullWidth label="Fecha" type="date" name="newDate" value={this.state.newDate} onChange={this.handleChange} /></div>
</DialogContent>
<DialogActions>
<Button onClick={this.handleDialogAcceptClick} name="accept" color="primary">
Aceptar
</Button>
<Button onClick={this.handleDialogCancelClick} name="cancel" color="secondary">
Cancelar
</Button>
</DialogActions>
</Dialog>
</div>
</div>
)
}
}
I have put console.log() statements right before calling <ProductPricesEntry> from <ProductPrices>, and inside <ProductPricesEntry> when rendering, and I can see that both console.log() statements are reached the first time, but the one inside <ProductPricesEntry> is not reached if this.props.currentProductPrices changes:
This is the value of this.props.currentPrices that is different, and I can see the change on Redux Tools:
The problem is that console.log() statement inside <ProductPricesEntry> is never reached, which means that it does not rerenders, in despite that the Redux state value that changed is sent to the component as a props, and displayed inside.
I guess I am doing something wrong, but I can't find it.
EDIT
This is the reducer that changes the state that must cause the rerendering:
case UPDATE_PRODUCT_PRICE_SUCCESS: {
if (state.currentPricesTable) {
let currentPricesTableProducts = [...state.currentPricesTableProducts];
let updatedProductIndex = currentPricesTableProducts.findIndex(product => product.id === action.payload.productPrice.id)
currentPricesTableProducts[updatedProductIndex]['next_price'] = action.payload.productPrice.next_price;
currentPricesTableProducts[updatedProductIndex]['due_date'] = action.payload.productPrice.start_date;
return {
...state,
currentPricesTableProducts: [...currentPricesTableProducts],
alert: {type: ALERT_SUCCESS, message: "El precio se actualizó existosamente."},
showMessage: true,
}
} else if (state.currentProduct) {
let currentProductPrices = [...state.currentProductPrices];
let updatedProductPriceIndex = currentProductPrices.findIndex(productPrice => productPrice.prices_table_product === action.payload.productPrice.prices_table_product)
currentProductPrices[updatedProductPriceIndex].next_price = action.payload.productPrice.next_price;
currentProductPrices[updatedProductPriceIndex].due_date = action.payload.productPrice.start_date;
return {
...state,
currentProductPrices: [...currentProductPrices],
alert: {type: ALERT_SUCCESS, message: "El precio se actualizó existosamente."},
showMessage: true,
}
} else {
return {
...state
}
}
}
As you can see, I replace the state variable currentProductPrices whit a brand new array.
I added a console.log() just before returning from the reducer, and I can see that the data is right. I can see the change:
I could never make it work as it was, but I found a wait around the problem, and I am sharing it in case it was useful for anyone.
I basically connected <ProductPricesEntry> to Redux store instead of sending the data as props from the parent.
class ProductPricesEntry extends React.Component {
constructor(props) {
super(props);
this.state = {
updateDialogOpen: false,
newPrice: null,
newDate: null,
price: null,
}
this.price = null;
this.handleUpdateClick = this.handleUpdateClick.bind(this);
this.handleDialogAcceptClick = this.handleDialogAcceptClick.bind(this);
this.handleDialogCancelClick = this.handleDialogCancelClick.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleUpdateClick = () => {
this.setState({updateDialogOpen: true});
}
handleDialogAcceptClick = () => {
this.props.updateProductPrice(
this.price.prices_table_product,
this.price.prices_table.id,
this.props.currentProductData.id,
this.state.newPrice, this.state.newDate
);
let price = {...this.state.price};
price.due_date = this.state.newDate;
price.next_price = this.state.newPrice;
this.setState({newPrice: null, newDate: null, updateDialogOpen: false, price: price});
}
handleDialogCancelClick () {
this.setState({newPrice: null, newDate: null, updateDialogOpen: null});
}
handleChange (event) {
this.setState({[event.target.name]: event.target.value})
}
render() {
this.price = this.props.currentProductPrices[this.props.index]
return (
<div key={this.props.index} style={{display: 'flex', background: 'white', backgroundColor: 'lightgray', marginTop: '2px', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<div className='col-10'>
<div fullWidth>
<h3>{this.price.prices_table.name}</h3>
</div>
<div fullWidth style={{display: 'flex'}}>
{this.price.current_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.price.current_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.price.due_date?
<div style={{textAlign: 'center'}} className='col-4'><strong>{this.price.due_date}</strong></div>:
<div style={{textAlign: 'center', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.price.next_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.price.next_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
</div>
<div fullWidth style={{display: 'flex'}}>
<div style={{textAlign: 'right'}} className='col-4'>Actual</div>
<div style={{textAlign: 'center'}} className='col-4'>Vigencia</div>
<div style={{textAlign: 'right'}} className='col-4'>Próximo</div>
</div>
</div>
<div className='col-1'>
<IconButton color="primary" aria-label={''.concat('update-price-', this.price.id)}>
<i className="zmdi zmdi-edit zmdi-hc-fw" onClick={this.handleUpdateClick} />
</IconButton>
<Dialog fullWidth open={this.state.updateDialogOpen} arialabelledby={''.concat('update-price-', this.price.id)}>
<DialogTitle id={"".concat("update-price-", this.price.id)}>Actualizar Precio</DialogTitle>
<DialogContentText>
<div style={{paddingLeft: '25px'}}><h2>{this.props.currentProductData.name}</h2></div>
<div style={{paddingLeft: '25px'}}><h2>{this.price.prices_table.name}</h2></div>
</DialogContentText>
<DialogContent>
<FormControl fullWidth>
<InputLabel htmlFor="newPrice">Precio</InputLabel>
<Input
type="number"
id="newPrice"
name="newPrice"
value={this.state.newPrice}
onChange={this.handleChange}
startAdornment={<InputAdornment position="start">$</InputAdornment>}
/>
</FormControl>
<div fullWidth><TextField fullWidth label="Fecha" type="date" name="newDate" value={this.state.newDate} onChange={this.handleChange} /></div>
</DialogContent>
<DialogActions>
<Button onClick={this.handleDialogAcceptClick} name="accept" color="primary">
Aceptar
</Button>
<Button onClick={this.handleDialogCancelClick} name="cancel" color="secondary">
Cancelar
</Button>
</DialogActions>
</Dialog>
</div>
</div>
)
}
}
const mapStateToProps = ({inventory}) => {
const {
currentProduct,
currentProductData,
currentProductPrices,
} = inventory
return {
currentProduct,
currentProductData,
currentProductPrices,
}
}
export default connect(mapStateToProps, {updateProductPrice}) (ProductPricesEntry);
Now it works as intended.

OnClick passing undefined

I am trying to pass an onClick value, but it passes undefined. Works well if it is not a Card/Paper/Div but I need this "button" to be a Card/paper/div
onClick={() => this.handleChange('bostadstyp')}
onClick={ value='villa', handleChange('bostadstyp')}
render() {
const { bostadstyp } = this.props;
const { auth } = this.props;
const { value, values, handleChange, handleClick } = this.props;
const { backgroundColori } = this.props;
const backgroundColor2 = "#F09515";
const aa = "";
// const imageUrl = window.innerWidth >= "1600px" ? Banner1 : Banner2;
// {if (!auth.uid) return <Redirect to="/loggain" />;}
return (
<div>
<img
className="stars3"
src={Logo}
width="15%"
align="center"
marginBottom="10px"
/>
<img src={Logo} width="15%" align="center" marginBottom="10px" />
<div style={{ backgroundColor: "#F1F1F1", padding: "30px" }}>
<h2
style={{
marginTop: "0px",
marginLeft: "10%",
color: "#F09515",
fontFamily: "Avenir",
fontWeight: "bold"
}}
>
{" "}
Dina Preferenser{" "}
</h2>
</div>
<form
className="background123"
style={{
backgroundColor: "#fdfdfd",
marginTop: "0px",
marginBottom: "0px"
}}
>
<Card
className="row xl12 l12 m12 s12"
style={{
marginLeft: "10%",
marginRight: "10%",
padding: "30px",
backgroundColor: "#fdfdfd"
}}
>
<br />
<div className="col xl6 l6 m12 s12">
<h4
style={{
fontFamily: "Avenir",
fontWeight: "bold",
color: "#F09515"
}}
>
1. Välj din boendestyp
</h4>
<p className="texti" style={{ fontSize: "16px" }}>
Vi behöver den här uppgift då vissa avtal endast gäller för
vissa anläggningstyper.
</p>
</div>
<div className="col xl6 l6 m12 s12">
<Card
className="row cardi xl12 l12 m12 s12"
style={{ width: "270%", backgroundColor: `white` }}
value={"villa"}
onClick={handleChange("bostadstyp")}
>
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6
className="texti"
style={{ fontSize: 16, textAlign: "right" }}
>
Villa/radhus
</h6>
</div>
</Card>
</div>
</Card>
</form>
</div>
);
}
I expect to 'values.bostadstyp' get the value 'villa'
because you are using function in the class so you must using this.handleChange instead of handleChange
<Card onClick={() => this.handleChange('bostadstyp' )}>
....
</Card>
You need to attach the onClick() listener to a <CardActionsArea/> component which should be nested inside your <Card/> component
Something like
<Card className="row cardi xl12 l12 m12 s12" style={{ width: '270%', backgroundColor: `white` }} value={'villa'} onClick={handleChange('bostadstyp' )} >
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6 className="texti" style={{ fontSize: 16, textAlign: "right" }}>Villa/radhus</h6>
</div>
</Card>
Also, I suggest looking into the <CardActions/> documentation, the example here shows how its used
Can you try below code in your card element:
<Card className="row cardi xl12 l12 m12 s12"
style={{ width: '270%', backgroundColor: `white` }} value={'villa'}
onClick={(e) => {
e.preventDefault();
this.handleChange('bostadstyp');
}}>
The issue may be due to one of the below reasons:
1. handleChange() not bound with this.
2. To pass values from onClick handler you should use (e) => func('value')
3. The click is happening inside form element, its better to include event.preventDefault()
You need user arrow function:
onClick={() => { this.handleChange('bostadstyp' ) }}
<Card className="row cardi xl12 l12 m12 s12" style={{ width: '270%', backgroundColor: `white` }} value={'villa'} onClick={() => { this.handleChange('bostadstyp' ) }} >
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6 className="texti" style={{ fontSize: 16, textAlign: "right" }}>Villa/radhus</h6>
</div>
</Card>
UPDATE
Handle Change from parent component:
Make sure your handleChange is bound properly by explicitly binding it or using an arrow function syntax:
this.handleChange = this.handleChange.bind(this) // In component's constructor
// or
handleChange = (value, input) => {
this.setState({
[input]: value
});
};
onClick expects a function to invoke, so you need to wrap your handler into one:
<Card onClick={() => handleChange('villa', 'bostadstyp')}></Card>

Resources