Using React how to switch the visibility of a nested component from a container component?

goal

I am trying to simulate a list management component in React and Redux based on Google Material Design Layout .

The list control allows you to create , rename, and delete items in a list without going to a new page.

Actions for renaming and deleting a list item will be displayed in the context menu component caused by clicking a link in each list item ..

The structure of the current component

I have a top-level Container component ListItemPage associated with Redux, which I use to maintain the state of the list before I make changes to the repository.

In ListItemPage, I present a list of items, and each item has a unique Menu Component

ListItemPage Component

class ListItemPage extends Component { constructor(props, context) { super(props, context); } onMenuClick(){} onRename(){} onDelete(){} render () { const { listItems } = this.props; return( <div> <ul> { listItems.map(listItem => <li> <a href={`/items/${listItem.id}`}> {listItem.title} </a> <a href="#" onClick={onMenuClick}> <i className="material-icons">more_vert</i> </a> <Menu showMenu={showMenu} onRename={onRename} onDelete={onDelete}/> </li> ) } <ul> <a href="#" onClick={null}> <i className="material-icons">add</i> </a> </div> ); } } function mapStateToProps(state, ownProps){ return { listItems: state.listItems } } function mapDispatchToProps(dispatch) { return { actions: bindActionCreators(listItemActions, dispatch) }; } export default connect(mapStateToProps, mapDispatchToProps)(ListItemPage); 

Menu component

 const Menu = (showMenu, onDelete, onRename) => { if(showMenu) { return( <nav> <a href="#" onDelete={onDelete}>Delete</a> <a href="#" onRename={onRename}>Rename</a> </nav> ); } return null; } export default Menu; 

Redux repository data structure

 let listItems = [ { id: 1, title: 'Item A' }, { id: 2, title: 'Item B' }, { id: 3, title: 'Item C' } ]; 

Problem

I cannot understand how I show and hide a unique menu component based on the onClickEvent list item .

I was thinking about how to get into the bool for this unqiue showMenu element , but I'm not sure where to define it for each element, or even if this is the best way to do this.

I know that I can use Refs to achieve this, but I would prefer not to indicate that it is recommended to use Refs as a last resort.

+5
source share
1 answer

Great first post! A good call to limit the use of refs too.

One approach may be to save some state in the ListItemPage component in which the menu should currently be displayed.

 constructor(props, context) { super(props, context); this.state = { showMenu: null }; } 

Then, in your onMenuClick function onMenuClick get the item ID to display the menu and assign a state.

 onMenuClick(id) { this.setState({ showMenu: id }); } 

This will be transferred to your Menu as follows.

 showMenu={this.state.showMenu === listItem.id} 

To close the menu, you just need to reset this.state.showMenu to null .

This assumes that only one menu will be displayed at a time. If it is not, let me know and I will update.

+3
source

Source: https://habr.com/ru/post/1261053/


All Articles