Filth
Filth

Reputation: 3228

Toggle Class Map On Component

How can I toggle the "isActive" within my state on my container via the "isSelected" click event within my component?

Please see the "List Accounts" component imported within my container. I'm passing the accounts data via props.

When I iterate through each account I want to check if "isActive" true or false.

I assume this will determine when the class is rendered.

Is it possible to have the "item" within the map function listen to state and update state within my "isSelected" function?

What is the best way to approach this?

Here is my container code:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import './index.css'; // styles from

import ProfileHeader from '../../../components/ProfileHeader';
import ListAccounts from '../../../components/ListAccounts';

import { fetchingPageData } from '../../../actions';


class WhosWatching extends Component {
  state = {
    accounts: [
      {
        isActive: false,
        isChild: false,
        name: 'Olivia',
        avatar: '/images/avatars/profile-img-03.png'
      },
      {
        isActive: false,
        isChild: false,
        name: 'Fred',
        avatar: '/images/avatars/profile-img-01.png'
      },
      {
        isActive: false,
        isChild: true,
        name: 'Dirk',
        avatar: '/images/avatars/profile-img-02.png'
      },
    ]
  }

  render() {
    const listAccounts = this.state.accounts;
    return (
      <div className="whos-watching-wrap container">
          <ProfileHeader />
          <h1>Who's Watching?</h1>
          <span>Select an account or add a new profile</span>
          <ListAccounts accounts={listAccounts} />
          <div className="whos-watching-cta">
            <button>Add Profile</button>
          </div>
      </div>
    );
  }
};

Here is my component for List Accounts:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import KidsIcon from '../../assets/svg/icons/kids.svg';

import './index.css';

export default class ListAccounts extends Component { 
    isSelected() {
    }

    render() {
        const { accounts } = this.props;
        return (
            <div className="list-accounts-wrap">
                {accounts.map((item, i) => {
                    return <div className="list-accounts-item is-selected" onClick={() => this.isSelected()} key={i}>
                        <img src={item.avatar} />
                        <div className="account-details-wrap">
                            <span className="account-name">{item.name}</span>
                            {item.isChild == true ? <KidsIcon /> : null }
                        </div>
                    </div>
                })}             
            </div>
        )
    }

}

Upvotes: 0

Views: 208

Answers (2)

Nishant Dixit
Nishant Dixit

Reputation: 5522

import React, { Component } from 'react';
import { connect } from 'react-redux';
import './index.css'; // styles from

import ProfileHeader from '../../../components/ProfileHeader';
import ListAccounts from '../../../components/ListAccounts';

import { fetchingPageData } from '../../../actions';


class WhosWatching extends Component {
  state = {
    accounts: [
      {
        isActive: false,
        isChild: false,
        name: 'Olivia',
        avatar: '/images/avatars/profile-img-03.png'
      },
      {
        isActive: false,
        isChild: false,
        name: 'Fred',
        avatar: '/images/avatars/profile-img-01.png'
      },
      {
        isActive: false,
        isChild: true,
        name: 'Dirk',
        avatar: '/images/avatars/profile-img-02.png'
      },
    ]
  }
  
   handleSelect(i) {
      let rawAccountsData = this.state.accounts;
      rawAccountsData = rawAccountsData.map((val, index) =>       {
          val.isActive = index == i ? true : false;
          return val;
      });
      this.setState({
          accounts: rawAccountsData
      });
  }

  render() {
    const listAccounts = this.state.accounts;
    return (
      <div className="whos-watching-wrap container">
          <ProfileHeader />
          <h1>Who's Watching?</h1>
          <span>Select an account or add a new profile</span>
          <ListAccounts accounts={listAccounts}  handleSelect = {this.handleSelect.bind(this)} />
          <div className="whos-watching-cta">
            <button>Add Profile</button>
          </div>
      </div>
    );
  }
};

import React, {
    Component
} from 'react';
import PropTypes from 'prop-types';
import KidsIcon from '../../assets/svg/icons/kids.svg';

import './index.css';

export default class ListAccounts extends Component {

    constructor(props) {
        super(props);
        this.state = {
            accounts: props.accounts
        }
    }
    componentWillReceiveProps(props, state) {
        if (JSON.stringify(props.accounts) != JSON.stringify(state.accounts))
            this.setState({
                accounts: props.accounts
            });
    }
  
   render() {
        const { accounts,handleSelect } = this.props;
        return (
            <div className="list-accounts-wrap">
                {accounts.map((item, i) => {
                    return <div className="list-accounts-item is-selected" onClick={() => handleSelect(i)} key={i}>
                        <img src={item.avatar} />
                        <div className="account-details-wrap">
                            <span className="account-name">{item.name}</span>
                            {item.isChild == true ? <KidsIcon /> : null }
                        </div>
                    </div>
                })}             
            </div>
        )
    }

}

Upvotes: 0

Alexander Vitanov
Alexander Vitanov

Reputation: 4141

Container

import React, { Component } from 'react';
import { connect } from 'react-redux';
import './index.css'; // styles from

import ProfileHeader from '../../../components/ProfileHeader';
import ListAccounts from '../../../components/ListAccounts';

import { fetchingPageData } from '../../../actions';


class WhosWatching extends Component {
  state = {
    accounts: [
      {
        isActive: false,
        isChild: false,
        name: 'Olivia',
        avatar: '/images/avatars/profile-img-03.png'
      },
      {
        isActive: false,
        isChild: false,
        name: 'Fred',
        avatar: '/images/avatars/profile-img-01.png'
      },
      {
        isActive: false,
        isChild: true,
        name: 'Dirk',
        avatar: '/images/avatars/profile-img-02.png'
      },
    ]
  }

  toggle = (i) => {
    const accounts = [...this.state.accounts]
    accounts[i].isActive = !accounts[i].isActive
    this.setState({ accounts })
  }

  render() {
    const listAccounts = this.state.accounts;
    return (
      <div className="whos-watching-wrap container">
          <ProfileHeader />
          <h1>Who's Watching?</h1>
          <span>Select an account or add a new profile</span>
          <ListAccounts toggle={this.toggle} accounts={listAccounts} />
          <div className="whos-watching-cta">
            <button>Add Profile</button>
          </div>
      </div>
    );
  }
};

List Accounts

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import KidsIcon from '../../assets/svg/icons/kids.svg';

import './index.css';

export default class ListAccounts extends Component { 

    state = {
      accounts: []
    }

    componentDidMount(){
      const { accounts } = this.props;
      this.setState({ accounts })
    }

    componentWillReceiveProps(nextProps){
      if(nextProps.accounts){
        this.setState({ accounts })
      }
    }

    isSelected(index) {
      this.props.toggle(index)
    }

    render() {
        const { accounts } = this.state
        return (
            <div className="list-accounts-wrap">
                {accounts.map((item, i) => {
                    return <div className="list-accounts-item is-selected" onClick={() => this.isSelected(i)} key={i}>
                        <img src={item.avatar} />
                        <div className="account-details-wrap">
                            <span className="account-name">{item.name}</span>
                            {item.isChild == true ? <KidsIcon /> : null }
                        </div>
                    </div>
                })}             
            </div>
        )
    }

}

Upvotes: 0

Related Questions