2

I am a new React learner, and I may have a situation with render() and findDOMNode.

What I have and what is the wrong behavior :

I'm quite new to React so, I may have done lots of mistakes there. I have a Webpart that I can change the appearance by applying a theme. This is done by selecting among themes on the PropertyPane. I developped a new theme for that WP. It is displaying well except for one little "bug" : When selecting that special theme on PropertyPane, my WP is not rendered in this theme, and I have to refresh the page to see it applied.

What I developed :

Here are the several parts of my Theme component :

export interface IToolBoxProps extends IItemsView {
  btnSettings?: IButtonSettings;
}
export default class Toolbox extends React.Component<IToolboxProps, {}> {
  constructor(props) {
    super(props);
  }

  public render(): React.ReactElement<IToolboxProps> {
    let result;
    let componentNode = ReactDOM.findDOMNode(this);
    let parentSection: Element;
    if (componentNode) {
      parentSection = this._findAncestor(componentNode, 'CanvasSection');
    }
    result = this.props.items.map((item, index: number) => {
      let stylesWP: string = '';

      if (parentSection.classList.contains('CanvasSection-xl12')) {
        //If Canvas Section is a full 12Col width
        if (index > 1) {
          stylesWP = styles.smallFormat;
        } else if (this.props.items.length === 1) {
          stylesWP = styles.bigFormat;
        }
      } else if (parentSection.classList.contains('CanvasSection-xl6')) {
        //If Canvas Section is 2col width
        if (index >= 1) {
          stylesWP = styles.smallFormat;
        } else if (index === 0) {
          stylesWP = styles.mediumFormat;
        }
      }
      return (
        <div className={styles.toolboxItem + ' ' + stylesWP}>
          <div className={styles.toolboxContent }>
            <span className={styles.toolboxSpanContainer }>
              <a href={item.URL}>{strings.SpanText}</a>
            </span>
            <h2 className={styles.toolboxItemTitle}>
              <a href={item.URL}>{item.Title}</a>
            </h2>
            <p className={styles.toolboxItemResume}>
              <a href={item.URL}>{item.Resume}</a>
            </p>
          </div>
        </div>
      );
    }, this);

    return <div>
      {
        this.props.items.length > 0 &&
          <div className={styles.toolboxContainer}>
            {result}
            </div>
      }
    </div>;
  }

  private _findAncestor(el: Element, className: string): Element {
    while ((el = el.parentElement) && !el.classList.contains(className)) {
      //turn while SP is loading -added this comment because Sonar.
    }
    return el;
  }


}

What is the error thrown in the console : When selecting the checkbox, I have the following error :

Uncaught TypeError : Cannot read property 'classList' of undefined on if (parentSection.classList.contains('CanvasSection-xl12')) {

This means that my parentSection is undefined. That means my componentNode is also undefined. I tried with componentDidMount() and componentWillMount() but had no interesting results. And, moreover, I read somewhere that findDOMNode is no longuer advised, it even is deprecated.

So, How can I get my current webpart's Node when first rendering the webpart depending on the PropertyPane's properties ? (and secondly, how can i retrieve its parent's node, because I know the way here is not conventional..)

Could you please advise me on how i could make my theme render when applying the theme ? because that bug aside, it is rendering perfectly ! Thank you.

Have a nice night

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.