简体   繁体   English

React js 有条件地将 class 渲染到特定的映射项

[英]React js conditionally rendering a class to a specific mapped item

I have been attempting to toggle a class on click so that when I click on one of the mapped items in my Tasks component, I add the 'complete' class and put a line through that item (crossing items off of a todo list).我一直试图在单击时切换 class,以便当我单击任务组件中的一个映射项目时,我添加了“完整”class 并在该项目上划了一条线(从待办事项列表中划掉项目)。 However with my current code set up, when I click on one element to add the class, all the other elements get crossed out as well and vice versa.但是,在设置了当前代码后,当我单击一个元素添加 class 时,所有其他元素也会被划掉,反之亦然。

Here is my current setup.这是我目前的设置。 The class 'complete' is what will add a line through one of the mapped items in the Tasks component. class '完成' 将通过任务组件中的一个映射项添加一行。

import { Container, Row} from 'react-bootstrap';
import {Link} from 'react-router-dom';
import axios from 'axios';

const List = (props) =>{
    return(
    <div>
       <Link style={{textDecoration:'none'}} to={`/lists/${props.listId}`} > <p className="list-item">{props.item}</p></Link>
    </div>
    ) 
}

const Tasks = (props) =>{
    return(
        <div onClick={props.onClick} className={props.className} >
        <div className='task-item' >
             <p >{props.item}</p>
        </div>
        </div>
    )
}


export default class Display extends Component {
    constructor(props){
        super(props)

        this.onCompletedTask = this.onCompletedTask.bind(this);

        this.state = {
            list: [],
            tasks:[],
            complete:false
        }
    }

    componentWillUpdate(nextProps){
        axios.get(`http://localhost:8080/lists/${this.props.match.params.listId}`)
        .then(response =>{
            this.setState({
                tasks:response.data
            })
        })
    }

    componentDidMount(){


        axios.get('http://localhost:8080/lists')
        .then(response=>{
            this.setState({
                list:response.data
            })
        })
        .catch(error =>{
            console.log(error)
        });


    }


    onCompletedTask(item){

        this.setState({ complete: !this.state.complete});
    }


    listCollection(){
        return(
         this.state.list.map(item=>{
             return(<List item = {item.title} listId={item._id} key = {item._id} />)

            })
        )
    }

    taskCollection(){
        return(
            this.state.tasks.map((item, index) =>{
                return(<Tasks onClick = {()=>this.onCompletedTask(item)} className={this.state.complete ? 'complete': ''} item={item.task}  key={index}/>)
            })
        )
    }



    render() {
        return (
            <div id='main' >
                <Container>
                    <Row>
                    <div className="sidebar">
                        <h1 style={{fontSize:"25pt"}}>Lists</h1>
                        <div className="list-menu">
                           {this.listCollection()}
                        </div>
                        <form action='/new-list' method='GET'>
                            <div style={{textAlign:'center'}}>
                            <button className='list-button' style={{fontSize:'12pt', borderRadius:'5px'}}>
                                + New List
                            </button>
                            </div>
                        </form>
                    </div>
                    <div className='tasks'>
                        <h1 style={{fontSize:'25pt'}}>Tasks</h1>
                        {this.taskCollection()}
                        <form action={`/lists/${this.props.match.params.listId}/new-task`} method='GET'>
                        <button className='task-button'>
                           +
                            </button>
                        </form>
                    </div>
                    </Row>
                </Container>


            </div>
        )
    }
}

Your state holds only a single completed value, which OFC toggle all tasks.您的 state 仅包含一个已完成的值,OFC 会切换所有任务。 You could instead store a map of completed tasks.您可以改为存储已完成任务的 map。

this.state = {
  list: [],
  tasks: [],
  complete: {}, // <--- use empty object as simple map object
}

Update onCompletedTask to store some uniquely identifying property of a task, like an id field更新onCompletedTask以存储任务的一些唯一标识属性,例如id字段

onCompletedTask(item){
  this.setState(prevState => ({
    completed: {
      ...prevState.completed, // <--- spread existing completed state
      [item.id]: !prevState.completed[item.id] // <--- toggle value
    },
  }));
}

Update.更新。 taskCollection to check the completed map by id taskCollection按 id 检查完成的 map

taskCollection = () => {
  const { completed, tasks } = this.state;
  return tasks.map((item, index) => (
    <Tasks
      onClick={() => this.onCompletedTask(item)}
      className={completed[item.id] ? "complete" : ""} // <--- check completed[item.id]
      item={item.task}
      key={index}
    />
  ))
};

编辑奇怪的pascal-9m486

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM