3

Im using React and want to do something like this:

enter image description here

Where the blue squares are initially hidden and show-up depending on which Colecao the user picks. So, some Classes with some Colecao inside where each one of them has "squares". This is my app.js:

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {

            activeTab: 'Classe 1',


            tabs: [
                {
                    tituloTab: 'Classe 1',
                    colecoes: [{
                        'Colecao 1': [
                            'A', 'B', 'C', 'D'
                        ],
                        'Colecao 2': [
                            'A', 'B', 'C', 'D', 'E'
                        ],
                    }]
                },
                {
                    tituloTab: 'Classe 2',
                    colecoes: [{
                        'Colecao 1': [
                            'A', 'B', 'C', 'D'
                        ],
                        'Colecao 2': [
                            'A', 'B', 'C', 'D', 'E'
                        ],
                    }]
                },
                {
                    tituloTab: 'Classe 3',
                    colecoes: [{
                        'Colecao 1': [
                            'A', 'B', 'C', 'D'
                        ],
                        'Colecao 2': [
                            'A', 'B', 'C', 'D', 'E'
                        ],
                        'Colecao 3': [
                            'A', 'B', 'C'
                        ],
                    }]
                },
                {
                    tituloTab: 'Classe 4',
                    colecoes: [{
                        'Colecao 1': [
                            'A', 'B', 'C', 'D'
                        ],
                        'Colecao 2': [
                            'A', 'B', 'C', 'D', 'E'
                        ],
                        'Colecao 3': [
                            'A', 'B', 'C'
                        ],
                        'Colecao 4': [
                            'A', 'B', 'C', 'D', 'E', 'F'
                        ],
                    }],
                }
            ],

            ThumbnailsColecoes: [
                {
                    tituloThumbnail: 'Costas',
                    texturas: ['A', 'B', 'C', 'D'],
                }
            ],

            colecaoSelecionada:
                '',

            toggleThumbnailsColecoes:
                false,
        };
    }

    changeActiveTab(tab) {
        this.setState({activeTab: tab});
    }

    activeTabContent() {
        const activeIndex = this.state.tabs.findIndex((tab) => {
                return tab.tituloTab === this.state.activeTab;
            }
        );
        return this.state.tabs[activeIndex].colecoes;
    }

    adicionarColecaoSelecionada(colecao) {
        this.setState({colecoesSelecionadas: colecao}, () => {
                this.setState({toggleThumbnailsColecoes: true})
            }
        )
    }

    render() {

        return (
            <div className={"container is-fluid"}>
                        <TabsArea
                            activeTab={this.state.activeTab}
                            tabList={this.state.tabs}
                            changeActiveTab={this.changeActiveTab.bind(this)}
                            colecoes={this.activeTabContent()}
                            addColecao={this.adicionarColecaoSelecionada.bind(this)}
                            colecoesThumbnails={this.state.ThumbnailsColecoes}
                            toggleThumbnails={this.state.toggleThumbnailsColecoes}/>
                    </Options>
                </section>
            </div>
        );
    }
}

export default App;

My tabsArea.js

class TabsArea extends Component {
    render() {

        return (

            <div className={["section", "tabsArea"].join(' ')}>

                <TabsHeader
                    activeTab={this.props.activeTab}
                    tabList={this.props.tabList}
                    changeActiveTab={this.props.changeActiveTab}
                />

                <TabContent
                    key={this.props.activeTab}
                    colecoes={this.props.colecoes}
                    addColecao={this.props.addColecao}/>
                <hr/>

                {//should get the Thumbnails for each "Colecao"
                    this.props.toggleThumbnails
                        ? <ThumbnailAreas
                            thumbnailAreas={this.props.colecoesThumbnails}>
                        </ThumbnailAreas>
                        : null
                }

            </div>
        )
    }
}

export default TabsArea;

tabContent.js

class TabContent extends Component {
    constructor(props) {
        super(props);
    }

    render() {

        return (

            <div>
                <ul className={"uList"}>
                    {this.props.colecoes.map((list) => {
                            return <li className={"li"}>
                                <a className={"has-text-black"}
                                   onClick={() => this.props.addColecao(list)}>
                                    {list} //should get the list of "Colecao"
                                </a>
                            </li>
                        }
                    )}
                </ul>
            </div>
        )
    }
}

export default TabContent;

titulo Tab is like my TabHeader, colecoes are each one of the list items and the array of letters should correspond to each one of the squares. The problem is that my tabs element is an object and I'm not sure how to pass it to an array. Also, where should I do it, in my app.js and pass the array as props or pass the object and convert into array on my component.

Thanks

2 Answers 2

1

Use the lodash library:

var arr = _.values(obj);

If you need it for other purposes in app.js, do it there, otherwise it doesn't matter.

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

3 Comments

Im sorry but I must be missing something. When I console.log my tabs and "let array = _.values(this.state.tabs);" I get the same result...
Sorry, my error. I thought that you need to convert an object to an array. Now I see that you have one item in the object, which is an array and each item of this array is an array with one item that is an object... Complicated... I would try to define a simpler state, but no time to dig into this now, sorry...
No problem. I dont know if this is the best way to set the state, later this will get data from an API and will be like a '3' layers options: Select a tab, each tab will have a list and each item on the list will have the respective thumbnails. Thanks, any help will be appreciated
0

If you will be using the array value in multiple places, then it makes the most sense to do the conversion in app.js and pass the array where it needs to go.

If you will only use the array value in one component, just pass the object into it and let it do whatever it needs that app.js shouldn't care about.

As for converting an object to an array, there are many ways one could do this and it depends on your specific use case. Looking at your example, it looks like tabs is already an array... am I missing something here?

5 Comments

Yes it's an array but its passed as an object with keys, right ? It's possible that I'm the one missing something, first time working around with this...
Just pass the array into whatever function you want in your component, and loop through it there... that should work, I don't see why it wouldn't. Everything in JavaScript is an "object" under the hood, so in that sense, yes, your array is an object, but it is still a loopable array.
Tried but Im getting "Objects are not valid as a React child (found: object with keys {Colecao 1, Colecao 2}). If you meant to render a collection of children, use an array instead."
Can you please show me how you are using your code? Edit your question with the updated code. Maybe you are using it poorly. Try doing something like <MyChildComponent tabs={this.state.tabs} /> or something along those lines. Since tabs is an array, that should work...
In your TabContent, you are doing this.props.colecoes.map(list => ...)... the argument will not be a list, it will be an object. Each iteration of the map function passes a single argument, not the list itself... Try changing that and the content of the addColecao method to expect an object and not a list.

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.