0

I have mapped list of data from JSON. When I clicked on of the item it should open a crawl with additional details from the same JSON file. I am able to map everything one I clicked bit I was not able to toggle. How do I do toggling.

This is my render method

 render() {
  return (
    <div>
      <h1>API</h1>
      <div>
        {this.state.apis.map(api => (
          <div
            key={api.id}
            id={api.id}
            onClick={this.handleCrawl}>
            {api.title}


          </div>
        ))}
      </div>
      <div>
      {this.state.apis.map(api => (
        <div
          key={api.id}
          id={api.id}>
          {this.state.showCrawl[api.id] && (

            <SwaggerUI url={api.opening_crawl}/>
          )}

        </div>
      ))}
    </div>
    </div>
  );
}

This is the method for toggling. When I clicked an item the SwaggerUI component shows up and If I clicked the same link it hides.

The problem is if I clicked the 2nd link 1st link still shows. I need other view to be closed.

handleCrawl = e => {
  const { id } = e.target;
  this.setState(current => ({
    showCrawl: { ...current.showCrawl, [id]: !current.showCrawl[id] }
  }));
};

2 Answers 2

1

just don't spread the previous state's props.

try this:

handleCrawl = e => {
  const { id } = e.target;
  this.setState(current => ({
    showCrawl: { [id]: !current.showCrawl[id] }
  }));
};

Because in your code:

initial state:

{showCrawl: {}}

Say first time you click the first one(id: 1), your state become:

{showCrawl: {1: true}}

then u click the second one(id: 2)

{showCrawl: {1: true, 2: true}}

That's not your expected. Right?

So just don't spread the property, it should be going well.

Sign up to request clarification or add additional context in comments.

3 Comments

My pleasure~~~.
How can I add a style when this clicked link is active in react.
U can give it a className. Like This: {this.state.apis.map(api => ( <div key={api.id} id={api.id}> {this.state.showCrawl[api.id] && ( <SwaggerUI className={this.state.showCrawl[api.id]?"active":""} url={api.opening_crawl}/> )} </div> ))}
0

In general, you can show or hide an element in a react component like this:

{this.state.showComponent ? (<Component/>) : (null)}

as an alternative, you can control the hiding/showing of the element in the component itself, with a show prop:

<Component show={this.state.showComponent} />

-- edit

I think I misunderstood your problem. Your problem is that you only want SwaggerUI to show for one thing at a time, but it's showing for multiple.

This is because of the way you designed your function,

handleCrawl = e => {
  const { id } = e.target;
  this.setState(current => ({
    showCrawl: { ...current.showCrawl, [id]: !current.showCrawl[id] }
  }));
};

You're only ever ADDING ids to showCrawl, not changing the ids that you toggled previously. You'll have to fix that function

1 Comment

Or shorter {this.state.showComponent && <Component />}.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.