I would like to create a custom button component that shows a loading spinner within itself when it's pressed and with a condition that can be externally defined which will tell the button to remove the spinner and return to its original appearance. Something like this:
<CustomButton
type="button"
className="btn btn-primary"
stopSpinningWhen={condition}
onClick={() => ...}
>
Click me
</CustomButton>
Currently, my buttons with a spinner look like this, which is super fine, but it's a pain to write repetitive code/states for each single button:
const [buttonSpinner, setButtonSpinner] = useState(false);
const onClickEvent = (ev) => {
setButtonSpinner(true);
if (condition) {
setButtonSpinner(false);
}
};
return (
<button
type="button"
className="btn btn-primary"
onClick={onClickEvent}
disabled={buttonSpinner}
>
{buttonSpinner ? (
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
></span>
) : (
"Click me"
)}
</button>
);
I'm using React 17.0.2.
Is it even possible?
CodePudding user response:
You can create your own custom button that receives isLoading
additionally.
const Spinner = (
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
/>
)
const CustomButton = (props) => (
<button
type="button"
className="btn btn-primary"
onClick={props.onClick}
disabled={props.isLoading}
>
{props.isLoading ? <Spinner /> : "Click me"}
</button>
)
const YourComponent = () => {
const [isLoading, setIsLoading] = useState(false)
const onClick = async(event) => {
setIsLoading(true)
doHeavyTask()
setIsLoading(false)
}
return (
<div>
<CustomButton isLoading={isLoading} onClick={onClick} />
</div>
)
}
CodePudding user response:
You use a loading property as your condition and just pass that as a prop to your custom button component. Something like this:
const myComponent = () =>{
const [loading, setLoading] = useState(false)
const myFunc = async () = {
setLoading(true)
//call api or do seomthing, after the process finishes set loading to false again
const resp = await fetch("myAPIURL")
console.log(resp.data)
setLoading(false)
}
return(
<CustomButton
type="button"
className="btn btn-primary"
spinning={loading}
onClick={() => myFunc()}
>
Click me
</CustomButton>
)
}