user2355058
user2355058

Reputation: 221

How to render dynamic components onClick

My code creates dynamic components/elements based on size of list of entities (in cache/memory). How can I modify this so that the onClick on line 32 (fab-click) adds yes another entity to the list. I ommitted the MainMenuElement class so lets assume it works. I think this is a problem of not knowing how to "think in react". Must I use react's state to achieve this, or is there a cleaner way?

I am actually adapting this from an HTML5/CSS3 app which used and am finding this to be much harder than just appending children from anywhere/any-time like with templates. Help.

createMainMenuElement(conversation){
    return <MainMenuElement conversation = {conversation} key ={conversation.key} />
}

createMainMenuElements(conversations) {
return conversations.map(this.createMainMenuElement)
}

generateData = function(){
    let usernames = ["tony","john","doe","test", "bruce"]
    let data = [];
    for(let i = 0; i < 5; i++){
        let temp = {key: i.toString(), username: usernames[i], timestamp: "4:30", subtitle: "The quick brown fox jumps over the lazy dog"}
        data.push(temp)
        this.mainMenuStack+=1;
    }
    return data;
};

handleFabClick() {
    console.log("test")
    let temp = {key:this.mainMenuStack.toString(), username: "Baby", timestamp: "12:30", subtitle: "The quick red cat jumps over the yellow dog"};
    this.createMainMenuElement(temp);
};



render(){
    return(
        <div className={cx('mainMenu')}>

            <div className={cx('mainMenu__element','mainMenu__element--pseudo')} onClick={this.handleFabClick}>

                <div className={cx('mainMenu__element__icon fab')} id="fab">
                    <div className={cx('fab__icon')}>&#43;</div>
                </div>

                <div className={cx('mainMenu__element__textWrapper')}>
                    <div className={cx('mainMenu__element__title')}>New Conversation</div>
                </div>

            </div>
            {this.createMainMenuElements(this.generateData())} //WORKS ON LOAD
            //WANT TO RENDER/APPEND DYNAMIC COMPONENTS HERE
        </div>
    )
};


}

Upvotes: 2

Views: 1073

Answers (1)

Eric Guan
Eric Guan

Reputation: 15982

You're thinking about the DOM, when you need to think about the data. In React, the DOM is purely a function of your data.

You'll need to store the dynamically created data, let's use an array

constructor(props){
    super(props)
    this.state = {
        elements:[]
    }
}

Then render the data. elements is empty for now, that's fine. But we know that eventually, the user will create data dynamically. The render function already handles that!

render(){
    return (
        <div>
            //other code
            {this.state.elements.map(this.createMainMenuElement)}
        </div>
    )
}

Now let's add the data.

handleFabClick() {
    let temp = {key:this.mainMenuStack.toString(), username: "Baby", timestamp: "12:30", subtitle: "The quick red cat jumps over the yellow dog"};
    this.setState({
        elements: [...this.state.elements, temp]
    })
};

We've now changed the state of the component, which causes it to rerender, which will display the new data. No DOM operations needed!

My code does not translate directly to your question, i'm merely showing you the React fundamentals. You said that you want to add elements to an existing list, so it looks like elements needs to contain ["tony","john","doe","test", "bruce"] by default. I hope you get the point though.

Upvotes: 1

Related Questions