React component failed to render without any error or warning



I am writing a React component like this. My goal is to render a checklist for shopping, with toggles (lower order component) that would update the state of this higher order component when clicked. It may look something like this

1.Fruits

Banana (Button)

Kiwi Fruit (Button)

2.Other snacks

Potato chips (Button)

Instant noodles (Button)

Sugarfree mint (Button)

let shopping_list = [
    {
        Fruits: [
            { Banana: "banana" },
            { "Kiwi fruit": "kiwi" },
        ]
    },
    {
        'Other snacks': [
            { "Potato chips": "potato_chips" },
            { "Instant noodles ": "instant_noodles" },
            { "Sugarfree mint": "sugar_free_mint" }]
    }
]

class ShoppingList extends Component {
    constructor(props) {
        super(props);
        this.btnClicked.bind(this);
        this.state = {
            banana: false,
            kiwi: false,
            potato_chips: false,
            instant_noodles: false,
            sugar_free_mint: false,
        }
    }

    btnClicked = (e) => {
        let obj = {};
        obj[e.currentTarget.id] = !(this.state[e.currentTarget.id]);
        this.setState(obj);
    }

    createToggle = (content, attribute) => {
        return (
            <Row key={attribute}>
                <Col>
                    {content}
                </Col>
                <Col xs="2">
                    <Chips label="&#x2713;"
                        id={attribute} onClick={this.btnClicked} />
                </Col>
            </Row>
        )
    }

    createNestedToggle = (shopping_list) => {
        //console.log("creating nested toggle")
        //console.log(this)
        shopping_list.map( (section, index) =>
        
        (   <React.Fragment key={index}>
            <Row className="table_text" style={{paddingTop: 5}}>
                <Col xs="12" style={{fontWeight: "bold"}}>
                    {index+1}.{(Object.keys(section))[0]}  
                </Col>
            </Row>

            {   (Object.values(section))[0].map((item) => {
                this.createToggle(
                    (Object.keys(item))[0],
                    (Object.values(item))[0]
                    )
                    }
                )
            }
        </React.Fragment>
            ))
    }


    render() {
        return (
            <div className="animated fadeIn">
                <Title type="title" content="Shopping list" />
                ...
                {/**Some rows and columns in here */}
                <div>
                    {this.createNestedToggle(shopping_list)}
                </div>
                <div>
                    {/**Some rows and columns in here */}
                </div>
            </div>)
    }
}

But the shopping list wasn’t rendered properly, it was missing. When I was debugging, I tried adding console log messages to the function createNestedToggle as you can see, and they’re actually logged. I am not sure what exactly is wrong with the second block.

Things I’ve tried

I have tried writing the createToggle part into a functional component to simplify the code – however, as I need the toggles to call back the HOC I have to make createToggle a part of ShoppingList class.

I am quite new to React JS(JS to be exact), so maybe I am doing the whole thing in a way that’s completely wrong. If you could suggest me a better way to do it, I would be very grateful as well. Any help or hint would be appreciated, thank you 🙂

Answer

After I have modified the createNestedToggle function as the following and it worked

createNestedToggle = (part_iii) => {
        return(
            <div>
                {part_iii.map( (section, index) =>
            
                <div key={index}>
                   ...
                    
                    {   
                        (Object.values(section))[0].map((item) => {
                            return(
                                this.createToggle(
                                    (Object.keys(item))[0],(Object.values(item))[0] )
                            )
                            
                            }
                        )
                    }
                    
                    
                </div>
                )}
            </div>
            
            )
        
    }

I was always confused by the arrow function notation and didn’t realise that it has to be ()=>{...return ...} . (Yep I should read the docs more carefully) I will leave this post here in case any future Googlers need it. Thanks for everyone’s answer.



Source: stackoverflow