I have a basic component that looks as follows.
class List extends React.Component {
constructor() {
super(...arguments);
this.state = {
selected: null,
entities: new Map([
[0, { 'name': 'kot'} ],
[1, { 'name': 'blini'} ]
])
};
}
render() {
return (<div>
<ul>{this.renderItems()}</ul>
</div>)
}
renderItems() {
return Array.from(this.state.entities.entries()).map(s => {
const [ id, entry ] = s;
return <li
key={id}
onClick={() => this.setState(state => ({ selected: id }))}
style={{
color: id === this.state.selected ? 'red' : 'black'
}}
>{entry.name}</li>
})
}
}
This works in order to allow me to click on any element and select it. A selected element will appear red. codepen for easy editing .
However, I want behavior that will unset any currently selected item if a click event was found that was not one of these <li>
elements.
How can this be done in React?
In your List
component, You can add
componentDidMount() {
window.addEventListener("click", (e) => {
let withinListItems = ReactDOM.findDOMNode(this).contains(e.target);
if ( ! withinListItems ) {
this.setState({ selected: null });
}
});
}
And in your renderItems
, change onClick
to
onClick={ (e) => {
// e.stopPropagation();
this.setState({ selected: id });
}
}
You can checkout this codepen http://codepen.io/anon/pen/LRkzWd
What @kubajz said is true, and hence i have updated the answer.
Random User's answer is correct, it may have one flaw - it relies on stopPropagation
and there is possibility that some piece of code may no longer work as expected - imagine collecting user's behaviour on page and sending metrics somewhere - stopPropagation will prevent bubbling, thus click is not recorded. Alternative approach is to check what was clicked in event.target
: http://codepen.io/jaroslav-kubicek/pen/ORXxkL
Also there is nice utility component for listening on document level: react-event-listener
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.