G
G
GreaterGlider2019-02-07 10:46:18
React
GreaterGlider, 2019-02-07 10:46:18

How to remove extra nodes when filtering Json?

Good day everyone! There is a similar json structure:

spoiler
const json = [
    {
        "type": "node",
        "title": "Title 1",
        "nodes": [
            {
                "type": "unit",
                "name": "Unit01",

            }
        ]
    },
    {
        "type": "node",
        "title": "Title 2",
        "nodes": [
            {
                "type": "node",
                "title": "Title 3",
                "nodes": [
                    {
                        "type": "unit",
                        "name": "Unit10",

                    },
                    {
                        "type": "unit",
                        "name": "Unit11",

                    },
                    {
                        "type": "unit",
                        "name": "Unit12",

                    }
                ]
            },
            {
                "type": "node",
                "title": "Title 4",
                "nodes": [
                    {
                        "type": "unit",
                        "name": "Unit20",

                    }
                ]
            }
        ]
    }
];

export default json;

I am outputting this json recursively through two components - Node and Unit, a complete application that can be run here:
spoiler
import React, { Component} from 'react';
import json from './data'

class Node extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            showUnits: false,
        }
        this.onClickHandle = this.onClickHandle.bind(this);
    }

    onClickHandle(event) {
        event.stopPropagation();
        this.setState({showUnits: !this.state.showUnits});
    }

    render() {

        const {showUnits} = this.state;

        return (

            <div className="node" onClick={this.onClickHandle}>{this.props.node.title}
                <ul className="node__title" >
                {showUnits && this.props.node.nodes.map(node => {
                    if (node.type === "node") {
                        return <Node node={node} value={this.props.value}/>
                    } else {
                        if (node.name.includes(this.props.value))
                            return <Unit unit={node} value={this.props.value}/>
                    }
                })}</ul>
            </div>
        )
    }
}


class Unit extends React.Component {

    render() {

        return (
                <li className="unit__name">{this.props.unit.name}</li>
        )
    }
}


class SearchField extends React.Component {

    constructor(props) {
        super(props);

        this.handleOnChange = this.handleOnChange.bind(this);

        this.state = {
            searchValue: "",
        }
    }

    handleOnChange(event) {
        const {value} = event.target;
        this.setState({searchValue: value})
    }

    render() {
        return (
            <React.Fragment>
                <form className="search-form">
                    <input type="text" className="search-form__input" placeholder="Поиск"
                           onChange={this.handleOnChange}/>
                </form>
                {json.map(node => <Node node={node} value={this.state.searchValue}/>)}
            </React.Fragment>
        )
    }
}


class App extends Component {

    render() {

        return (
            <main>
                <SearchField/>
            </main>
        );
    }
}

export default App;

A filter by Unit objects is also implemented.
Here's what the list looks like expanded:
5c5be1d04e3ac569043810.png
And here's what I get when filtering:
5c5be1efe46fa516457237.png
The problem is that I want to hide those nodes in which no units were found (that is, the Title 2, Title 3 and Title 4 nodes in the screenshot). I tried to do it through a callback in the Unit component, as well as through React.Children, but it doesn’t work. Help with advice, at least in which direction to dig, I have already broken my whole head.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2019-02-07
@GreaterGlider

We make a method that will recursively bypass the data and discard elements whose name does not contain the search string and does not have nested elements (either did not exist initially, or they were discarded). And instead of the original data, we display the result of this method. Somehow so .

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question