简体   繁体   中英

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

I am working on filter component being made with React.JS. A few of those filtering components are embedded in a panel ( 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:

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. Hence, I see state printed to the console. However, this.setState({ showInitiatives: false }) does not seem to do anything. My modal does not hide, and the second (etc) time I click on the <li> , showInitiatives still set to true .

This is because click event bubbles up the DOM tree combined with async nature of setState

First li.onClick fires calling selector which calls setState({ showInitiatives: false})

Then a.onClick fires calling setState({ showInitiatives: true }) . You could check it is true say by adding log statement to it.

Now you have 2 pending updates

{ showInitiatives: false}
{ showInitiatives: true}

which when merged is noop.

You need to either stop event propagation inside li.onClick by calling e.stopPropagation() or rethink what a.onClick handler is doing.

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.

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