I'm currently inheriting an ES6 React base component in the following way:
model.js (base component):
class ModelComponent extends React.Component {
render() {
// Re-used rendering function (in our case, using react-three's ReactTHREE.Mesh)
...
}
}
ModelComponent.propTypes = {
// Re-used propTypes
...
};
export default ModelComponent;
Then I have two extending components that both look basically like this:
import ModelComponent from './model';
class RobotRetroComponent extends ModelComponent {
constructor(props) {
super(props);
this.displayName = 'Retro Robot';
// Load model here and set geometry & material
...
}
}
export default RobotRetroComponent;
(Full source code here)
This appears to work fine. Both models are showing up and working as I would expect.
However, I have read in multiple places that inheritance is not the correct approach with React - instead I should be using composition. But then again, Mixins are not supported in React v0.13?
So, is the approach I'm taking above OK? If not, what's the problem, and how should I do this instead?
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
Inheritance allows the app to do the coupling between the parent-child component and reuse properties such as state values and function in its child components. React does not use inheritance except in the initial component class, which extends from the react package.
The renderComponent is a must API for every React. js component.
React does not render two sibling elements unless they are wrapped in a fragment.
The Facebook team recommends 'using idiomatic JavaScript concepts' when writing React code, and since there is no mixin support for ES6 classes, one should just use composition (since you are just making use of idiomatic Javascript functions).
In this case, you can have a composeModal
function that takes a component and returns it wrapped in a higher-order, container component. This higher-order component will contain whatever logic, state, and props you want passed down to all of its children.
export default function composeModal(Component){
class Modal extends React.Component {
constructor(props){
super(props)
this.state = {/* inital state */}
}
render() {
// here you can pass down whatever you want 'inherited' by the child
return <Component {...this.props} {..this.state}/>
}
}
Modal.propTypes = {
// Re-used propTypes
...
};
return Modal
}
Then you can use the composition function like so:
import composeModal from './composeModal';
class RobotRetroComponent extends React.Component {
constructor(props) {
super(props);
this.displayName = 'Retro Robot';
// Load model here and set geometry & material
...
}
render(){
return /* Your JSX here */
}
}
export default composeModal(RobotRetroComponent);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With