0
votes

I am pretty new to react and I have been stuck in a problem for quite a good time.

I have a component DisplayList that iterates through an array of objects and displays them in a list form. Each object becomes a button. I also have another component to render the single view of each item on the list once the item is clicked. My problem is that I get to render the single view of all my items at once INSIDE my displayList component. All I want is to be able to click on the list item and render another component with ONLY info about the item I clicked on and passing my "project" as the props to it. what should I do? What is my error?

My DisplayList component (the part that matters for this problem):

export default class DisplayList extends Component {
  constructor() {
    super();
    this.state = {
      displaySingle: false
    };
  }

  handleClick = () => {
    this.setState({
      displaySingle: true
    })
  }

  render() {
    if (this.props.projects && this.props.projects.length > 0) {
      return (
        <List component="nav">
          {this.props.projects.map(project => (
            <div className="all-content-wrapper" key={project.id}>
              <ListItem button value={project} onClick={this.handleClick}>
                {this.state.displaySingle ?
                  <DisplaySingleItem project={project} /> :
                  null
                }
                <ListItemICon>
                  <img
                    className="single-item-img-in-list-view"
                    src={project.img}
                  />
                </ListItemICon>
3

3 Answers

1
votes

You are just a hint away from doing it the right way:

Change the condition in your onClick() as:

onClick={()=>this.handleClick(project.id)}
         { this.state.displayProject_id === project.id ?
           <DisplaySingleItem project={project} /> : 
            null
         }

Now define handleClick() as:

    handleClick = (project_id) => {
    this.setState({
                displayProject_id: project_id
               })

    }

Don't forget to define the initial state in the constructor:

this.state = { 
           displayProject_id:null
 };
0
votes
<div className="all-content-wrapper" key={project.id}>
     <ListItem button value={project} onClick={()=>this.handleClick(project)}>
            {this.state.displayProject && this.state.displayProject.id==project.id ?
              <DisplaySingleItem project={project} /> :
              null
            }
            <ListItemICon>
              <img
                className="single-item-img-in-list-view"
                src={project.img}
              />
            </ListItemICon>
    </ListItem>
</div>

change your JSX like the above so you pass the current project to handleClick and change handleClick like the following.

handleClick = (project) => {
    this.setState({
      displayProject : project
   })
 }

It should now display the <DisplaySingleItem/> for the clicked project.

0
votes

For you to be able to show only the project that was selected it is important that you have a reference to it. Right now your handleClick() function does not accept and parameters or data that you can identify the project that was selected.

My solution for you is to pass the project as a parameter to handleClick(project). So your code should look like.

export default class DisplayList extends Component {
  constructor() {
    super();
    this.state = {
      displaySingle: false
    };
  }

  handleClick = (project) => {
    this.setState({
      selectedProject: project, // <- use this state to show your popup or 
                                     // whatever view you're using
      displaySingle: true
    })
  }

  render() {
    if (this.props.projects && this.props.projects.length > 0) {
      return (
        <List component="nav">
          {this.props.projects.map(project => (
            <div className="all-content-wrapper" key={project.id}>
              <ListItem button value={project} onClick={() => this.handleClick(project)}>
                {this.state.displaySingle ?
                  <DisplaySingleItem project={project} /> :
                  null
                }
                <ListItemICon>
                  <img
                    className="single-item-img-in-list-view"
                    src={project.img}
                  />
                </ListItemICon>
   )
 }