React Filter library
Here is a review of the code. While some my comments / suggestions are related to JavaScript and not to react specifically, these do reflect common practices in React code.

I put a live version with the changes on codesandbox. I created a small API to have some data for the fetch request. I also added a css file to test the active behavior for the selected filter topics.

Library.jsx


componentDidMount():

It is a common practice in react to use the map function to create a new array. Also, you can change the code so that setState is only called once (for conciseness):

componentDidMount() {
  fetch("https://demo5925186.mockable.io")
    .then(res =&gt; res.json())
    .then(data =&gt; {
      const topics = data.topics.map((name, index) =&gt; ({
        name,
        id: index,
        active: false
      }));

      this.setState({
        lib: data.lib,
        filteredLib: data.lib,
        topics
      });
    })
    .catch(err =&gt; console.log(err));
}

render()

It can make your JSX easier to read if you extract properties from the state on the first line using object destructuring assignment:

const { filteredLib, topics } = this.state;


It seems like you would always want to show the Filters component (the topic selection), even if filteredLib.length is equal to 0.

render() {
    const { filteredLib, topics } = this.state;
    return (
      &lt;div className="library-container"&gt;
        &lt;Filters topics={topics} handleClick={this.handleFilters} /&gt;
        {filteredLib.length === 0 ? (
              &lt;h4&gt;Wir konnten leider nichts finden :(&lt;/h4&gt;
        ) : (
          &lt;div className="column column--content"&gt;
            &lt;ul className="cards"&gt;
              {filteredLib.map(item =&gt; (
                &lt;LibraryItem key={item._id} {...item} /&gt;
              ))}
            &lt;/ul&gt;
          &lt;/div&gt;
        )}
      &lt;/div&gt;
    );
}

handleFilters

I changed state.filter to state.selectedTopic and the input argument name from topic to newTopic.

Similarly to componentDidMount, the newTopics array can be created with map (you could convert the ternary to an if-else statement). You can use the spread operator on each object to create a new object.

It seems like state.filter would never be an empty string because handleFilters always sets state.filter to whichever topic was selected.  To fix this, you can compared the new selected topic to the existing one. If they are the same, the new selected topic should be set to an empty string.

handleFilters = newTopic =&gt; {
    const { topics, selectedTopic } = this.state;

    const newTopics = topics.map(
      topic =&gt;
        topic.id === newTopic.id
          ? { ...topic, active: !topic.active }
          : { ...topic, active: false }
    );

    // If the new selected topic is same as the old one
    // We will set state.selectedTopic to ""
    const newSelectedTopic =
      newTopic.name === selectedTopic ? "" : newTopic.name;

    this.setState(
      {
        topics: newTopics,
        selectedTopic: newSelectedTopic
      },
      () =&gt; {
        this.filterLib();
      }
    );
  };



Filters.jsx

It is common to define functional components with const, and the parameters can be destructured in the function definition.

There is no need for the handleClick method. You can change the name of props.handler to props.handleClick, and call it directly.

const Filters = ({ topics, handleClick }) =&gt; (
  &lt;div className="column column--filters"&gt;
    &lt;h3 className="title"&gt;Filter&lt;/h3&gt;
    &lt;ul className="filters"&gt;
      {topics.map(topic =&gt; (
        &lt;li
          key={topic.id}
          className={
            topic.active ? "filters__item active" : "filters__item"
          }
          onClick={() =&gt; handleClick(topic)}
        &gt;
          {topic.name}
        &lt;/li&gt;
      ))}
    &lt;/ul&gt;
  &lt;/div&gt;
);

export default Filters;