简体   繁体   English

根据输入文本字段的焦点来反应条件渲染

[英]React conditional rendering depending on focus of input text field

I have a Search component, which renders these child components: SearchBar and Suggestions. 我有一个Search组件,它呈现以下子组件:SearchBar和Recommendations。

I want to render Suggestions only if the input in SearchBar has focus. 我只想在SearchBar中的输入具有焦点时才呈现“建议”。 I used the event onFocus for this, which triggers a callback inside the parent component (Search). 为此,我使用了onFocus事件,该事件触发了父组件(搜索)内部的回调。 When I click outside the input field i use onBlur. 当我在输入字段之外单击时,我使用onBlur。 The conditional rendering works, however there's a problem. 条件渲染有效,但是存在问题。

Inside my Suggestions component, I list a few elements. 在“建议”组件中,列出了一些元素。 If the user clicks on an element, I trigger a onClick event. 如果用户单击某个元素,则会触发一个onClick事件。 The problem is, however, that when the user clicks on an element, the onBlur event is naturally also triggered which causes the entire Suggestions component to disappear. 但是,问题在于,当用户单击某个元素时,自然也会触发onBlur事件,这会导致整个“建议”组件消失。 This results in the onClick event not being triggered.. 这将导致不会触发onClick事件。

I am really stuck on this problem, any ideas? 我真的陷在这个问题上,有什么想法吗?

One solution is not to use OnBlur, but instead capture click / or focus events on a root element, then check to see if you want to then close. 一种解决方案是不使用OnBlur,而是捕获单击/或将事件集中在根元素上,然后检查是否要关闭。

Below is a working snippet showing this, click into the edit and a list will appear, you can then click on the list items and it will console log one or two without closing. 下面是一个显示此内容的工作片段,单击进入编辑,将出现一个列表,然后您可以单击列表项,它将控制台记录一两个日志而不关闭。 But if you click on anything else it will then close. 但是,如果您单击其他任何按钮,它将关闭。

The example just uses a simple className check to see if the current target element has the class no-close , if not it will close the list. 该示例仅使用简单的className检查来查看当前目标元素是否具有类no-close ,否则将关闭列表。

 class Form extends React.Component { constructor () { super(); this.state = {showList: false}; } render () { return <div onClick={ (e) => { if (!e.target.classList.contains("no-close")) this.setState({showList: false}); } }> <input className="no-close" onFocus={() => this.setState({showList: true})}/> {this.state.showList ? <div> <ul> <li className="no-close" onClick={() => console.log("one")}>One</li> <li className="no-close" onClick={() => console.log("two")}>Two</li> </ul> </div> : null} <div><br/><br/>Just some text, clicking this should not keep list open, if it's open</div> </div> } } ReactDOM.render(<Form/>, document.getElementById("mount")); 
 <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script> <div id="mount"></div> 

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

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