Jayavel
Jayavel

Reputation: 3407

Add dynamic attribute in ReactJS

Button component which renders a button based on prop dataSrc send by parent App.

 export default class Button extends React.Component {
    constructor(props) {
        super(props);
    }
    render(){
        return(
            <div>
                {this.props.dataSrc.map((element, index) => {
                    return <button 
                        key={index}
                        className={`btn btn-default ${element.class} ${element.secondary ? "btn-secondary" : ""}`}
                        type="button"
                        disabled={element.disabled}>
                            {element.label}
                    </button>
                })} 

            </div>

        );      
    }
}

Parent component App sends dataSrc to Button.

class App extends React.Component {
    constructor(props) {
        super(props);
    }
    render(){
        const btnSrc = [
            {
                "label":"Save",
                "class":"user_information_save",
                "disabled":false
            },
            {
                "label":"Cancel",
                "class":"userCancel",
                "disabled":false
            }
        ]
        return <Button dataSrc={btnSrc} /> 
    }
}

Now everything is fine. Here comes the scenario, the btnSrc in App(parent) component will be look alike:

const btnSrc = [
        {
            "label":"Save",
            "class":"user_information_save",
            "disabled":false
        },
        {
            "label":"Cancel",
            "class":"userCancel",
            "disabled":false,
            "data-id": "someID", // this will be dynamic
            "name": "someName" // this will be dynamic
            "onClick": this.someFunctionaName // this will be dynamic
        }
    ]

Now the src is changed, but little confused in Button component to render those dynamic data added recently.

export default class Button extends React.Component {
    constructor(props) {
        super(props);
    }
    render(){
        return(
            <div>
                {this.props.dataSrc.map((element, index) => {
                    return <button 
                        key={index}
                        className={`btn btn-default ${element.class} ${element.secondary ? "btn-secondary" : ""}`}
                        type="button"
                        disabled={element.disabled}

                        //here i want to have those dynamic data "data-id": "someID", "name": "someName" here 
                        // and i want to add onClick also here which will be loaded from btnSrc

                        >
                            {element.label}
                    </button>
                })} 

            </div>

        );      
    }
}

How can i add those dynamic custom object values to existing Button component and I do not know how to bind events to in .map too. Code Demo

Any help would be helpful.

Upvotes: 2

Views: 7951

Answers (1)

Mayank Shukla
Mayank Shukla

Reputation: 104369

I think, there are two solutions possible:

1- Use Spread syntax ..., and pass put all the passed values on button, by this was you don't need define each property separately. Like this:

return <button 
        key={index}
        className={`btn btn-default ${element.class} ${element.secondary ? "btn-secondary" : ""}`}
        type="button"
        {...element}
    >
        {element.label}
</button>

Now if you pass onClick then only it will be assigned otherwise not.

2- Use destructuring and assign the default value if not passed from the parent.

Like this:

{this.props.dataSrc.map((element, index) => {
    const {onClick=null, dataGrid=''} = element;
    return <button 
            key={index}
            className={`btn btn-default ${element.class} ${element.secondary ? "btn-secondary" : ""}`}
            type="button"
            disabled={element.disabled}
            onClick={onClick}
            data-grid={dataGrid}
        >
            {element.label}
    </button>
})} 

Working Example.

Upvotes: 5

Related Questions