简体   繁体   English

React调用在无状态组件的props中传递的调用setState的函数

[英]React invoking function calling setState passed in props of a stateless component

I am working on filter component being made with React.JS. 我正在使用React.JS制作过滤器组件。 A few of those filtering components are embedded in a panel ( div ). 这些过滤组件中的一些嵌入在面板( div )中。 The wrapping parts of the panel look like the below: 面板的包裹部分如下所示:

        Initiative <a onClick={() => {this.setState({ showInitiatives: true })}} className="milestone-list-link" href="#initiative">
          {this.state.selectedInitiative}
          <InitiativeSelector
            initiatives={initiatives || {}}
            show={this.state.showInitiatives}
            selector={
              () => {
                console.log('called selector state:', this.state)
                this.setState({ showInitiatives: false })
              }
            }
          />
          <FilterIcon />
        </a>

My <InitiativeSelector /> looks like the below: 我的<InitiativeSelector />如下所示:

const InitiativeSelector = ({initiatives, show, selector}) => {
  return (show) ? (
    <div className="list-filter">
      <div>
        <input placeholder="Search..." />
      </div>
      <ul>
        {
          Object.values(initiatives).map((initiative, i) => <li onClick={() => {selector()}} key={i}>{initiative.name}</li> )
        }  
      </ul>
    </div>
  ) : null
}

When I run this, my selector does get called. 当我运行它时,我的selector会被调用。 Hence, I see state printed to the console. 因此,我看到状态被打印到控制台。 However, this.setState({ showInitiatives: false }) does not seem to do anything. 但是, this.setState({ showInitiatives: false })似乎没有任何作用。 My modal does not hide, and the second (etc) time I click on the <li> , showInitiatives still set to true . 我的模态不会隐藏,第二次(等)单击<li>showInitiatives仍设置为true

This is because click event bubbles up the DOM tree combined with async nature of setState 这是因为单击事件将DOM树与setState异步特性结合在一起

First li.onClick fires calling selector which calls setState({ showInitiatives: false}) 首先li.onClick触发调用setState({ showInitiatives: false})调用selector

Then a.onClick fires calling setState({ showInitiatives: true }) . 然后a.onClick触发调用setState({ showInitiatives: true }) You could check it is true say by adding log statement to it. 您可以通过添加log语句来检查它是否正确。

Now you have 2 pending updates 现在您有2个待处理的更新

{ showInitiatives: false}
{ showInitiatives: true}

which when merged is noop. 合并时是noop。

You need to either stop event propagation inside li.onClick by calling e.stopPropagation() or rethink what a.onClick handler is doing. 您需要通过调用e.stopPropagation()来停止li.onClick内部的事件传播,或者重新考虑a.onClick处理程序正在做什么。

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

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