Вот причина, по которой ваше lgShow остается верным.
Это объяснение будет немного длиннее.Поэтому, пожалуйста, потерпите меня.
Вот что вы сделали.
Вы добавили ContainerModal в качестве дочернего элемента div (className ="item-list") внутри renderList метода, к которому прикреплен слушатель onClick.Когда вы нажимаете на элемент списка, он работает нормально, и появляется модальный, но когда вы нажимаете на кнопку закрытия на модальных вещах, они становятся подозрительными.
Это происходит из-за того, что прослушиватель onClick div (className = "item-list") вызывается после того, как прослушиватель щелчков ContainerModal вызывается, устанавливая lgShow в true снова.Это поведение называется всплывающим событием , когда и родитель, и потомок получают событие снизу вверх (то есть, потомок, получающий первое событие, за которым следует родитель).Чтобы проверить это, добавьте console.log в прослушиватель onClick элемента div.
Вот ссылка на вопрос github для объяснения всплывающих событий
Решение
Первым и главным предложением было бы вывести ContainerModal из метода renderList в корневой div.Это потому, что сейчас для каждого вашего элемента списка создается ContainerModal, который не нужен.Например, если у вас есть 10 пользователей в списке, вы создаете 10 ContainerModal (Чтобы убедиться в этом, увеличьте количество пользователей, и вы можете увидеть, как оттенок модала становится темнее.)
Решение указанной выше проблемыВозьмите ContainerModal на корневой уровень, где он onClick не будет совпадать с onClick div (className = "item-list") в renderList, и ваша проблема будет решена.
Вот модифицированное решение.
import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import { connect } from 'react-redux';
import { getAllUsers,getMessages } from './../actions';
import { bindActionCreators} from 'redux';
import { Button, Modal } from 'react-bootstrap';
import ContainerModal from './../components/popup_modal';
// parent component
class MainContainer extends Component {
constructor(props, context) {
super(props, context);
this.state = {
lgShow: false
};
}
componentWillMount(){
this.props.getAllUsers();
}
renderList = ({list}) => {
if(list){
return list.map((item)=>{
return(
<div key={item._id} className="item-list" onClick={() => this.setState({lgShow: true})}>
<div className="title">{item.firstName} {item.lastName}</div>
<div className="body">{item.age}</div>
<div>
{/* <ContainerModal lgShow={this.state.lgShow} lgClose={this.lgClose}/> */}
</div>
</div>
)
})
}
}
lgClose = () => {
this.setState({lgShow:false});
console.log('im in the function');
}
render() {
console.log(this.state);
return (
<div className="App">
<div className="top">
<h3>Messages</h3>
<Link to="/form">Add</Link>
</div>
<div className="messages_container">
{this.renderList(this.props.users)}
</div>
<ContainerModal lgShow={this.state.lgShow} lgClose={this.lgClose}/>
</div>
);
}
}
function mapStateToProps(state) {
return {
messages:state.messages,
users:state.users
}
}
function mapDispatchToProps (dispatch) {
return bindActionCreators({getAllUsers,getMessages},dispatch);
}
export default connect(mapStateToProps,mapDispatchToProps)(MainContainer);
import React from 'react';
import { Button, Modal } from 'react-bootstrap';
// child component
const ContainerModal = (props) => {
return (
<div>
<Modal
size="lg"
show={props.lgShow}
onHide={ props.lgClose }
aria-labelledby="example-modal-sizes-title-lg"
>
<Modal.Header closeButton>
<Modal.Title id="example-modal-sizes-title-lg">
Large Modal
</Modal.Title>
</Modal.Header>
<Modal.Body>item</Modal.Body>
</Modal>
</div>
)
}
export default ContainerModal;
Обратите внимание на измененную позицию модального контейнера.Остальная часть кода в порядке.
Я также загрузил рабочее решение в изолированную программную среду кода.Посмотрите на это.
Надеюсь, это поможет.