How to change the style of a reactjs component by code

Viewed 755

I need to change the style of some child components of a react components. Something like this:

import React, { Component } from 'react';

class Parent extends Component {
   onClickHandler = (event) => {
      this.props.children[0].props.style.marginLeft = "-100%";
   }
   render() {
      <div onClick={this.onClickHandler}>
         {this.props.children}
      </div>
   }
}

export default Parent;

The error i'm getting is:

TypeError: Cannot add property marginLeft, object is not extensible

May you help me guys?

Thanks a lot !!

3 Answers

The error you are getting is because you cannot modify props, since those are immutable. A simpler approach can be done using plain CSS and simple state management.

With this technique, you need a state variable to know when to add the class modifier. That class modifier is in charge of overriding the styles of the child component.

The JS would look like this:

import React, { Component } from "react";

class Parent extends Component {
  constructor() {
    this.state = {
        bigMargin: false
    };
  }

  onClickHandler = (event) => {
      event.preventDefault();
      this.setState({ bigMargin: true });
  };

  render() {
    return (
        <div className={`parent-class ${bigMargin && 'big-margin'}`} onClick={this.onClickHandler}>
            {this.props.children}
        </div>
    );
  }
}

export default Parent;

And the CSS can be something as simple as this (or as complex as you may want)

.big-margin:first-child {
  margin-left: -100%;
}

React props are immutable and you can't change them, they are read only and you can't add new properties. This is done via Object.preventExtensions, Object.seal and Object.freeze.

To "fix" the error partialy you should define marginLeft in the first child of your Parent component

<Parent>
    <p style={{marginLeft: '0'}}>1</p>
    <p>2</p>
</Parent>

You will get now a new Error :

 TypeError: "marginLeft" is read-only

Imagine having the ability to change props, and you pass the same prop to many children, one of them change it value, this will lead to unexpected behavior.

Try something like Grab the element by its id on click

document.getElementById("demo").style.marginLeft = '-100px'

Or use react refs to grab the element

Related