Skip to content

Instantly share code, notes, and snippets.

@mplibunao
Last active February 27, 2019 06:21
Show Gist options
  • Select an option

  • Save mplibunao/b7146adf230ad015143b66348d0a5947 to your computer and use it in GitHub Desktop.

Select an option

Save mplibunao/b7146adf230ad015143b66348d0a5947 to your computer and use it in GitHub Desktop.
React Notes

References:

Props
Lifting State and Handling events
Conditional Rendering

Structure

  • Container will contain ALL the state and eventhandlers (handleOnClick, handleOnChange functions etc)
state = {
  artists: [] // {}
}

handleOnClick = (e) => {
  // put your logic here
  this.setState({ whatever: e.target.value });
}

  • Container renders two component (one for each column)
// import the components here
import ArtistItem from 'components/ArtistItem';
import ArtistDetails from 'components/ArtistDetails';
import ArtistRequests from 'components/ArtistRequests';
class SomeComponent extends React.Component {
  state = {};
  
  render() {
    return (
      <div className'container'>
        <div className'col'>
          <ArtistItem />
        </div>
        <div className='col'>
          <ArtistDetails />
          <ArtistRequest />
        </div>
      </div>
    )
  }
}
  • Component's job will be to to render the view (what you see) with the help of the data
  • You do this with using props
// ({ firstName, lastName }) is the same as (props)
// except now you don't have to use props.firstName, props.lastName
// read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment for more info
// skip to object destructuring
const ArtistItem = ({ firstName, lastName }) => {
  return (
    <div className='container'>
      <div>{firstName}</div>
      <div>{lastName}</div>
    </div>
  );
}
  • Pass the data (from state) to the component
  • Pass the event handler functions to the component
class SomeComponent extends React.Component {
  state = {
    artists: [
      { id: 1, firstName: 'aaa', lastName: 'vbbb' },
      { id: 2, firstName: 'ccc', lastName: 'ddd' },
    ]
  };
  
  onArtistItemClick = (id) => {
    // do something
  }

  render() {
    return (
      <div className'container'>
        <div className'col'>
          {this.state.artists.map(artist => {
            return (
              <ArtistItem
                key={artist.id}
                artist={artist}
                onArtistItemClick={this.onArtistItemClick}
              />
            )
          })}
        </div>
        <div className='col'>
          <ArtistDetails />
          <ArtistRequest />
        </div>
      </div>
    )
  }
}
  • Use a selectedArtist to track the id of the item selected state
state = {
  artist: [],
  selectedArtist: 1
};

handleArtistItemClick = (id) => {
  // put your logic here
  this.setState({ selectedArtist: id });
}
  • To pass the id from the component back to the container do the ff:

  • PS: you can attach an Onclick handler in divs, span and other elements too

  • What's happening here is we are lifting the state back up to the parent component so it can store it in the state (Lifting state)

  • To make it easy to deal with the state, keep it as much as possible in your top level component (ArtistManagementPage.js, TagManagementPage.js)

  • Reference: https://reactjs.org/docs/lifting-state-up.html

const ArtistItem = ({ id, firstName, lastName, onArtistItemClick }) => {
  return (
    <div className='container' onClick={() => onArtistItemClick(id)}>
      <div>{firstName}</div>
      <div>{lastName}</div>
    </div>
  );
};
class SomeComponent extends React.Component {
  state = {
    artists: [
      { id: 1, firstName: 'aaa', lastName: 'vbbb' },
      { id: 2, firstName: 'ccc', lastName: 'ddd' },
    ],
    selectedArtist: 1,
  };

  onArtistItemClick = (id) => {
    // do something
  }

  render() {
    return (
      <div className'container'>
        <div className'col'>
          {this.state.artists.map(artist => {
            return (
              <ArtistItem
                key={artist.id}
                artist={artist}
                onArtistItemClick={this.onArtistItemClick}
              />
            )
          })}
        </div>
        <div className='col'>
          <ArtistDetails
            artist={this.state.artists.find(artist => artist.id === this.state.selectedArtist)}
          />
          <ArtistRequest />
        </div>
      </div>
    )
  }
}

Using Conditional Rendering

# Pseudocode only
# Just look at line 219
# Just take note of how we're checking if `selectedArtist === artist.id` before rendering the details
# else just return null (which is the equivalent of not rendering anything)
return artist.map(artist => (
  <ArtistItem
    onClick={() => this.onSelectItem(artist.id)}
    artist={artist}
  />
  {this.state.selectedArtist === artist.id ? <ArtistDetails artist={} /> : null}
))
state = {
  showDiv: false,
  showDiv2: '',
  showDiv3: 0,
  showDiv4: undefined,
  showDiv5: 'this is a string'
}

render() {
  // won't show anything
  return this.state.showDiv && <div>showing</div>

  // won't show anything
  return this.state.showDiv2 && <div>showing</div>

  // won't show anything
  return this.state.showDiv3 && <div>showing</div>

  // won't show anything
  return this.state.showDiv4 && <div>showing</div>

  // will return `<div>showing</div>
  return this.state.showDiv5 && <div>showing</div>
}
  • Important! Make sure to use && when mapping an array because using .map on undefined will cause an error
state = {
  artists: null
}

// This will crash your program because `undefined` has no `map`
return artists.map(artist => <ArtistItem artist{artist} />)

// Do this instead
return artists && artists.map(artist => <ArtistItem artist={artist} />)
// Will not render anything (since `artist.map` will not even execute) if artist is `falsy`
// Else, will render the `ArtistItems`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment