Hi I am new to React and typescript. I am working on adding checked attribute for a checkbox but find it tricky. I searched across SO but still couldn't get it closer to working.
Here is what I am trying to do:
I am creating three checkbox ponents using a single child ponent[shown here]. They all have their own values that I need to pass dynamically.
interface ItemProps {
readonly className?: string;
readonly checked: boolean | undefined;
readonly accentedUnchecked?: boolean;
readonly imageUrl: string;
readonly errorMessage?: string;
readonly statusChecked?: boolean | undefined;
readonly onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
readonly hasError?: boolean;
readonly title?: string;
readonly value?: number;
readonly description?: React.ComponentType;
}
export class Item extends React.Component<
ItemProps,
{
readonly isExpanded: boolean;
readonly checkboxStatus: boolean;
readonly temp: boolean;
readonly checked: boolean;
}
> {
constructor(props) {
super(props);
this.state = {
isExpanded: false,
checkboxStatus: false,
temp: false,
checked: this.state.temp
};
this.handleClick = this.handleClick.bind(this);
this.onChange = this.onChange.bind(this);
}`
private onChange(e: React.ChangeEvent<HTMLInputElement>) {
this.setState({ temp: e.currentTarget.checked });
}
private readonly handleClick = e =>
this.props.onChange({
currentTarget: { checked: e.currentTarget.checked }
} as any);
render() {
const unchecked = this.props.accentedUnchecked && this.props.checked === false;
return (
<label className="checkbox">
<input
type="checkbox"
checked={this.onChange} //Not working
onChange={this.props.onChange}
onClick={this.handleClick}
id={"test"}
data-id="0"
/>
);
The problem is I am not sure how to set the checked attribute, based onClick. when I use
checked={this.props.checked}
I am getting all checkboxes checked. Or if I use
checked={this.handleClick}
I get error saying
cannot assign void to a boolean" in typescript.
Any suggestion on how this can be resolved will be very helpful
Thanks in advance
Hi I am new to React and typescript. I am working on adding checked attribute for a checkbox but find it tricky. I searched across SO but still couldn't get it closer to working.
Here is what I am trying to do:
I am creating three checkbox ponents using a single child ponent[shown here]. They all have their own values that I need to pass dynamically.
interface ItemProps {
readonly className?: string;
readonly checked: boolean | undefined;
readonly accentedUnchecked?: boolean;
readonly imageUrl: string;
readonly errorMessage?: string;
readonly statusChecked?: boolean | undefined;
readonly onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
};
readonly hasError?: boolean;
readonly title?: string;
readonly value?: number;
readonly description?: React.ComponentType;
}
export class Item extends React.Component<
ItemProps,
{
readonly isExpanded: boolean;
readonly checkboxStatus: boolean;
readonly temp: boolean;
readonly checked: boolean;
}
> {
constructor(props) {
super(props);
this.state = {
isExpanded: false,
checkboxStatus: false,
temp: false,
checked: this.state.temp
};
this.handleClick = this.handleClick.bind(this);
this.onChange = this.onChange.bind(this);
}`
private onChange(e: React.ChangeEvent<HTMLInputElement>) {
this.setState({ temp: e.currentTarget.checked });
}
private readonly handleClick = e =>
this.props.onChange({
currentTarget: { checked: e.currentTarget.checked }
} as any);
render() {
const unchecked = this.props.accentedUnchecked && this.props.checked === false;
return (
<label className="checkbox">
<input
type="checkbox"
checked={this.onChange} //Not working
onChange={this.props.onChange}
onClick={this.handleClick}
id={"test"}
data-id="0"
/>
);
The problem is I am not sure how to set the checked attribute, based onClick. when I use
checked={this.props.checked}
I am getting all checkboxes checked. Or if I use
checked={this.handleClick}
I get error saying
cannot assign void to a boolean" in typescript.
Any suggestion on how this can be resolved will be very helpful
Thanks in advance
Share Improve this question edited Mar 23, 2020 at 10:48 Regokonda asked Mar 23, 2020 at 9:14 RegokondaRegokonda 971 gold badge2 silver badges11 bronze badges 04 Answers
Reset to default 3If you want to be quick, online demo has been added at the bottom. I rewrite almost all those stuff.
Some notice points:
- Since you want to reuse the child checkbox, you shouldn't write the handler functions inside the child, expose then to parents instead.
- Both
onClick - MouseEvent
andonChange - ChangeEvent
would be fine since it's fully controlled, the only thing we need to pass is its id. The checked status is held by the parents. - You can write nested checked logic inside the child, based on the props passed from parents.
import * as React from "react";
import "./styles.css";
const data = [
{ id: 1, checked: 1 },
{ id: 2, checked: 0 },
{ id: 3, checked: 1 }
];
export default function App() {
const [checkedList, setCheckedList] = React.useState(
data.map(x => !!x.checked)
);
const onChangeHandler = (
e: React.ChangeEvent<HTMLInputElement>,
id: number
) => {
const list = [...checkedList];
list.splice(id - 1, 1, !list[id - 1]);
setCheckedList(list);
};
return (
<div className="App">
<h1>Checkboxes</h1>
{data.map((item, idx) => (
<InsuranceItem
id={item.id}
key={item.id}
checked={checkedList[idx]}
onChange={onChangeHandler}
/>
))}
</div>
);
}
interface InsuranceItemProps {
readonly id?: number;
readonly className?: string;
readonly checked: boolean | undefined;
readonly accentedUnchecked?: boolean;
readonly imageUrl?: string;
readonly errorMessage?: string;
readonly statusChecked?: boolean | undefined;
readonly onChange: (
event: React.ChangeEvent<HTMLInputElement>,
id: number
) => void;
// readonly handleClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
readonly hasError?: boolean;
readonly title?: string;
readonly value?: number;
readonly description?: React.ComponentType;
}
class InsuranceItem extends React.Component<
InsuranceItemProps,
{
// readonly isExpanded: boolean;
// readonly checkboxStatus: boolean;
// readonly temp: boolean;
// readonly checked: boolean;
}
> {
constructor(props: InsuranceItemProps) {
super(props);
this.state = {
// isExpanded: false,
// checkboxStatus: false,
// checked: false
};
}
render() {
const { id = 0, accentedUnchecked, checked, onChange } = this.props;
// const unchecked = accentedUnchecked && checked === false;
return (
<label className="checkbox">
<input
type="checkbox"
checked={checked}
onChange={e => onChange(e, id)}
id={id.toString()}
data-id="0"
/>
</label>
);
}
}
Actually you will not needed onClick
prop here, and checked
prop is only expect boolean value
As per react docs, this should be the right way if you have multiple check boxes
handleInputChange(event) {
const target = event.target;
const value = target.name === 'isGoing' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
Mistake 1
You're setting function instead of boolean for checked
. Which is wrong. I don't know how TypeScript is allowing you to do that
Mistake 2
Using onClick()
and onChange()
together. Don't do that. Use only one. Prefer onChange()
to onClick()
here.
Corrected code
// Parent Component
handleClick = (checked: boolean, id: string) => {
this.setState(prevState => ({
checked: { ...prevState.checked, [id]: checked }
})) // or however you structured this state
}
// Child ponent
// Creating ID as variable
const id = 'test';
handleClick = ev => {
// Avoid passing `ev` directly
this.props.handleClick(ev.currentTarget.value, id)
}
return (
<input
type="checkbox"
checked={this.props.checked}
onChange={this.handleClick}
id={id}
data-id="0"
/>
)
you can use MCheckbox
import :
import { MCheckbox } from '../@material-extend';
function :
function handleLike(e) {
if (e.target.checked) {
// your code here when it checked
} else {
//your code here when it is not checked
}
}
jsx :
<MCheckbox
onChange={(e) => handleLike(e)}
defaultChecked={false}
size="small"
color="error"
icon={<Icon icon={heartFill} />}
checkedIcon={<Icon icon={heartFill} />}
/>