Nick
Nick

Reputation: 59

Hide sub-component in components generated with map() in React

I'm working on a todo app. When a task is clicked

setState({displayTaskMenu: true})

is called,

but I also need to hide the taskMenu on all the other Task components where displayTaskMenu is true.

What is the correct way of doing this with React?

This is the render method of Task component:

render() {
    let { task } = this.props;

    return (
        <div onClick={this.toggleMenu}>
            <div>
                {task.label}

                {this.state.displayTaskMenu && (<TaskMenu />)}

            </div>
        </div>
    );
}

Tasks are sorted by days, and the render of Day component is:

render() {
    return (
        <div style={this.state.dayStyle}>
            <span style={this.state.dateStyle}>{this.props.date}</span>
            <h1>{this.props.day}</h1>

            {this.props.tasks &&
                this.props.tasks.map(
                    (task, i) => <Task key={i} task={task}/>
                )}
        </div>
    );
}

Upvotes: 1

Views: 174

Answers (1)

brandonwang
brandonwang

Reputation: 1653

Since only one Task component should open their TaskMenu, the Day component needs to keep track of which Task it is by using state. So, the Day component should pass in a custom onClick function to each Task an update its state.

Day component:

render() {
    return (
        <div style={this.state.dayStyle}>
            <span style={this.state.dateStyle}>{this.props.date}</span>
            <h1>{this.props.day}</h1>

            {this.props.tasks &&
                this.props.tasks.map(
                    (task, i) => <Task 
                                  key={i}
                                  task={task}
                                  displayMenu={this.state.displaying == i}
                                  onClick={ () => this.setState({displaying: i}) }/>
                )}
        </div>
    );
}

Task component:

render() {
    let { task } = this.props;

    return (
        <div onClick={this.props.onClick}>
            <div>
                {task.label}

                {this.props.displayMenu && (<TaskMenu />)}

            </div>
        </div>
    );
}

Using this approach, you don't need the toggleMenu function in the Task component anymore.

Upvotes: 1

Related Questions