0

I am slightly new to react and ES6 in general and am trying to create a resuable app drawer component connected to a navbar.

I am trying to use the classnames npm package to conditionally render the Dawer component to the right or left of the screen based on the value of props.isLeft passed into the component however I am experiencing some weirdness that I think may be related to the component life-cycle or javascripts weird psuedo implementation of classes but am unsure which...

export default class Drawer extends  Component {
    constructor(props){
        super(props);
        const {isOpen,isLeft} = props;
        const aligned = cx({
            [styles.drawer_left] : this.isLeft,
            [styles.drawer_right] : !this.isLeft,
        });
        this.state = {
            isOpen: isOpen
        }
    }

    render(){
        console.log(this.aligned);
        return(
            <div className={this.aligned}>
                {this.props.children}
                djkdjd
            </div>
        )
    }

}

The log statement is telling me that the aligned property is undefined however this is confusing to me. If i change const aligned to 'this.aligned', aligned is then defined outside of the constructor.I believe that is because it is being created as an object on the Drawer prototype, however I don't understand why this is?I also am confused on the proper way to destructure an object inside of a class based component if you cannot declare a constant? Would you use a spread operator or maybe object.assign?

I know that I could solve this by just make the component stateless and it would work fine and also I believe I've read there is an es6 feature which allows you to remove the constructor call altogether and define properties on the class directly. However I am asking because I just want to understand the language more and why this doesn't work?

koalamo
  • 199
  • 3
  • 11
  • `const aligned` is not a property of the object; it is just a local variable in the constructor. Do `this.aligned = `. – trincot Feb 11 '18 at 11:48
  • "*If i change const aligned to 'this.aligned', aligned is then defined outside of the constructor.*" - no, what makes you think so? You still assign to it inside the constructor, right? – Bergi Feb 11 '18 at 12:32

1 Answers1

0

Local variables and constants within the constructor do not automatically become properties of the instance. Only ones you specifically assign to the instance as properties do. aligned is never saved as a property on the instance. It's just a local constant within the constructor. The same is true for your isLeft.

To make aligned a property, assign to this.aligned; since isLeft isn't a property, don't use this.isLeft to access it:

    this.aligned = cx({
//  ^^^^^
        [styles.drawer_left] : isLeft,
// ----------------------------^
        [styles.drawer_right] : !isLeft,
// ------------------------------^
    });

(Or make isLeft property if you want it to be one.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875