React - Set loading state only on specific clicked button

Viewed 6115

Here is my current code

class cart extends Component {
    state = { loading: [] };

    addToCart = (e, id) => {
        let loading = this.state.loading.slice();
        loading[e] = true;
        this.setState({
            loading,
        })
    };
    render() {
        const { data } = this.props;

        return (
            <div>
            {data.map(catering => {
                const { menus } = catering;

                return (
                    <Row>
                    {menus.map(menu => (
                        <Col xs={12} md={12} lg={6} key={menu.id} className="m-bottom-15">
                        <Card style={{ height: '165px', border: 0, overflow: 'hidden' }}>


                        <CardActions>
                        <LoadingButton
                        className="button small primary pull-right"
                        loading={thi.state.loading || false}
                        onClick={e => this.addToCart(e, menu.id)}
                        >
                        <MdAdd size={18} color={white} />
                        <span className="font-14 font-400">Add to cart</span>
                        </LoadingButton>

                        </CardActions>
                        </Card>
                        </Col>
                        ))}
                    </Row>

                    );
            }
        }

There will be around 20 button when the map function is done.

What I want to achieve is: every time users click add to cart button, I will call the ajax to save the cart and show loading for the specific clicked button. After ajax is done, return the state back to normal.

On my current code I haven't put my ajax call yet, I still want to make sure the loading button work on press. Right now its not working.

How can I achieve this?

Thanks.

3 Answers

for the hooks guys this is what I did

const [isLoading, setIsLoading] = useState([]);
<button
        type="button"
        disabled={isLoading[item.username]}
        className="btn btn-success btn-rounded btn-sm my-0"
        onClick={()=>activateOrDeactivate( item.activated,item.username)}
      >      {isLoading[item.username] && <i className="fa fa-circle-o-notch fa-spin"></i>}
      {isLoading[item.username]&& <span> Activating...</span>}
      {!isLoading[item.username]&& <span>Activate</span>}</button>


 const activateOrDeactivate = (valTrueOrFalse,newusername) => {
    let loading = isLoading.slice();
    loading[newusername] = true;
    setIsLoading(loading)
    let config = {
      headers: {
        Authorization: "Bearer " + state.token
      },
    };

    api.post(
      "process-activation",
      {
        activated: !valTrueOrFalse,
        username:newusername
      },
      config
    ).then(
      response => {
        getAllUsers()
        let loading = isLoading.slice();
        loading[newusername] = false;
        setIsLoading(loading)
Related