Is the following an anti pattern in React? I like the pattern because it gives me context in static functions when a component has been instantiated. Then later I can import the class and call a static method to modify state. Or can this be done in a better way?
// componentA.js
function bleedContext() {
ComponentA.staticMethod = ComponentA.staticMethod.bind(this)
}
export default class ComponentA {
static staticMethod() {
this.setState({foo: 'bar'})
}
constructor() {
this.state = {}
bleedContext.call(this)
}
render() {
return (
...
)
}
}
// componentB.js
import ComponentA from 'path/to/componentA'
export default class ComponentB {
handleClick() {
ComponentA.staticMethod()
}
render() {
return (
<button onClick={this.handleClick} />
)
}
}
This is clearly an antipattern and possibly a mistake, depending on conditions. Static class method shouldn't operate with class instance.
staticMethod
is bound to specific component instance and usessetState
, this could be only justified a class is a singleton (though a singleton is often an antipattern, too). This will result in bugs and memory leaks if more than one class instance is expected, and every React component is expected to have more than one instance, at least for testing.A proper way for two independent components to interact with each other in React is to have a common parent component that provides this interaction, e.g.:
The problem with example above is that this will require to pass
modalRef
prop deeply if<SomeComponentThatUsesModal>
is nested.This problem is solved with React context or other third-party global state solutions like Redux.
This can be done with React 16.3 context API, considering that
Modal
class instance hasopen
method:Then for any deeply nested component modal object with
open
and close methods will be available via context:Here's a demo.