How I Connected React Components to External JS: A Developer’s Story
- Published on
- • 2 mins read•--- views
Due my current work task i have a case - to call a modal created as a React-component from SharePoint Ribbon. In two words, SharePoint ribbon is a structure that contains buttons and js-functions binded for it. When you push the button, js function binded for it calls... hope you understand :). And i started to google: how to interact with react module from outer js, how to change react state from outer js, force re-render react component from pure js and so on... So, the main problem is: you cannot bind react-component function to ribbon button because it hides deep inside into webpack js bundle. Also, i need to change React Module state because i want rerender component when i click the button. So, i make the fiddle and looks like it works correctly - https://jsfiddle.net/o6ujb5g2/. It is not SharePoint ribbon, but almost the same. Idea is to attach function from react modal to global window object. This object exist from almost anywhere.
Steps:
- I created a stub-function in pure js for window.func that i want to override from component (it is for safety, if some problems with component will happens due it's render)
- In component i initialize a func with business logic, that changes component state
- On componentDidMount i override global window.func to module.func
- PROFIT!!!
Source Code listings:
HTML
<script>
window.toggleModal = function(isOpened) {
console.log(`[x] Loading... Passed value: ${isOpened}`);
}
</script>
<input type="button" onclick="js:window.toggleModal(true);" value="click me"/>
<div id="app" var1="test"></div>
React Module
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.state = {
isModalOpened: false,
items: [
{ text: Learn JavaScript, done: false },
{ text: Learn React, done: false },
{ text: Play around in JSFiddle, done: true },
{ text: Build something awesome, done: true }
]
}
}
componentDidMount = () => {
window.toggleModal = this.toggleModal;
}
toggleModal = (isOpened) => {
this.setState({
...this.state, isModalOpened: isOpened
});
}
render() {
return (
<div>
<h2>Todos:</h2>
<ol>
{this.state.items.map(item => (
<li key={item.id}>
<label>
<input type=checkbox disabled readOnly checked={item.done} />
<span className={item.done ? done : }>{item.text}</span>
</label>
</li>
))}
</ol>
{this.state.isModalOpened && (
<React.Fragment>
<p>modal opened!</p>
<input type=button onClick={() => this.toggleModal(false)} value=close />
</React.Fragment>)}
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector(#app))