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