I had to rewrite a class as a function in JS/React, but I am having some trouble to get the hook to work in the function.
function Switch(props) {
const [isActive, setIsActive] = React.useState();
function handleClick() {
setIsActive(!isActive);
}
const className = `switch ${props.color} ${props.isActive ? 'on' : 'off'}`;
return (
<div className={className}>
<button className="img" onClick={handleClick} />
<h3>{props.title}</h3>
</div>
);
}
ReactDOM.render((
<Switch title="Happiness" color="blue" isActive={false} />
), document.querySelector('#root'));
I tried changing the handleClick function (and the setIsActive within it), but I can't get it to work. Thanks in advance for the help!
Note: Didn't add the CSS, as that part is working fine.
You're taking the isActive from props instead from state. To get this working you need to change
const [isActive, setIsActive] = React.useState();
to
const [isActive, setIsActive] = React.useState(props.isActive);
and
const className = `switch ${props.color} ${props.isActive ? 'on' : 'off'}`;
to
const className = `switch ${props.color} ${isActive ? 'on' : 'off'}`;
Also if you want to apply prop changes from outside you need to add an useEffect hook as such
useEffect(() => {
setIsActive(props.isActive)
}, [props.isActive])
You are trying to change props the component receives by a state within the child components. Props are(shall be) immutable. If you wish to alter the behaviour of component,
copy the props in the state variable
const [isActive, setIsActive] = React.useState(props.isActive);
use function form of state update. More important in cases where the new state depends on previous state
function handleClick() { setIsActive(prevState=>!prevState.isActive); }
Update reference to state variable instead of received prop value
const className = switch ${props.color} ${isActive ? 'on' : 'off'};
You also need to look at component state isActive. You can logical Or it with your props isActive(which acts only as a default value here):
const className = `switch ${props.color} ${
props.isActive || isActive ? "on" : "off"
}`;