Overwriting a single (nested) property when extending a React class - reactjs

I am rather new to React.js, I believe I understood the major concepts, and I am struggling to find documentation on how to overwrite a single property of a class I am declaring.
In on of my components, I define a new class MyColumn based on a class from Ant Design. The architecture (of inheritance rather than composition) was already made by others, and I am not able to change that.
import { Table } from "antd";
const { Column } = Table;
// ...
class MyColumn extends Column<Interfaces.myViewEntry> { } // <---
At the moment, the column headers just flows downward, I need either ellipsis dots (and a mouse-over with the full column label), or a proper word wrap. Probably, the latter is easier.
To reach that goal, I want to set the property style: { 'white-space': 'unset' } (and just that property) for MyColumn since I read that this will allow me to get proper word-wrap for the column headers.
Could somebody please elaborate what to put into the brackets in the line I marked with <--?
Background
In interfaces.tsx, I defined something like the following
export interface myViewEntry{
LastName: string,
FirstName: string,
Result: number,
}
References
Overwriting and Extending Prototype
React.js: setState overwriting, not merging
How to do word-wrap for data using react-table?
How can we configure the Header of ant design table component?
How to update nested state properties in React
Reactjs-documentation on Components and Properties and on Composition and Inheritance

in my opinion it's better to wrap ant-design components with you own ones and add additional properties to that.
For example:
import { Table } from 'antd';
export default function MyTableColumn({ children, ...rest }) {
//...useState, useRef, useEffect, whatever you need.
return <Table.Column {...rest}>{children}</Table.Column>
}

Related

Design question about useContext in react hooks: similar components but with different context

I have a Chart component that consists of Cell components. Both the Chart and the Cells use useContext hooks and I provide that context in an outer layer. I want to create a new chart that is similar, but uses a different context. For instance, the original chart stores and looks up information based on keys that are different: when I populate the original context it looks like: {'player 1': [], 'player 2': [], 'player 3' ...}, but the new context will look like: {'You': [], 'Your opponent': []}
Should I pass a parameter/flag to the Chart component that tells it what context to use? And then I could do something like: const [selectedCombos, handleSelectedDispatch] = usePlayers ? useContext(OriginalContext) : useContext(OtherContext)
Can I even do something like that? I know it smells bad, but the only alternative I see is copying the Chart/Cell components to a new file, changing the context it uses and renaming it. That also sucks. What is the right approach here?
I've tried simply copying the code to a new component and using a different context, but that stinks too.
Passing a flag is kind of bad because what if you think in the future, what happens if the Cell can use 3 different context? Or more?
Ternary will be bad. And you will be importing context that won't be used.
What you can do is pass a prop with the context.
e.g.
// File that render the cell.
import OnlyTheContextYouNeed from '../mycontext/OnlyTheContextYouNeed'
...
<Cell usedContext={OnlyTheContextYouNeed } />
...
//Cell.jsx
...
const [selectedCombos, handleSelectedDispatch] = useContext(props.usedContext)
This way you don't have to import all the contexts you have in Cell and you only import the context you will need and use when you render Cell.

Should you create a custom eventWrapper component for react-big-calendar?

There is no documentation for adding a eventWrapper and I've seen a few comments saying it's not meant to be overwritten. Should we be using this or trying to create custom eventWrapper component to override this exsisting one?
For me I don't want the .rbc-event-label also want to dynamically in JS change the styling. Or should I be just changing things in the CSS?
You can dynamically apply additional classes and styling to your events by using the eventPropGetter property. This property takes a function that should return an object of class names and styles to be applied to an event (automatically added to the eventWrapper).
const eventRenderProps = (event, start, end, isSelected) => {
let result = {};
// Code to conditionally add 'className' or 'style' to the result
return result; // {className?: String, style?: Object}
}
//
<MyCalendar eventPropGetter={eventRenderProps} />
It's important to note that this method is called on every displayed event, and will get called again on each as an event is selected or changed/updated. Also important to note that className is to be a String, and not an object, so if you require several classes you will need a space delimited list of class names.

class name convention in react material-ui framework

Is there a class name convention used in material ui library? I'm currently using material-ui-next. I notice class names like "MuiFormControl-root-124" all over the place with numbers appended to class name. For Paper element "MuiPaper-root-18 MuiPaper-shadow2-22 MuiPaper-rounded-19". I just can't see a pattern here.
Is there a convention which I'm missing. It would be easier to understand this framework if it made sense like Bootstraps grid classes. All help much appreciated. Thank you.
In material-ui v1, class names are non-deterministically generated at run time, so there is no convention you should adhere to. That's described here in the docs:
You may have noticed that the class names generated by our styling solution are non-deterministic, so you can't rely on them to stay the same.
However, that does not matter because you should never be using raw CSS class names in the first place. Instead, you use withStyles to set the appropriate styles for each component:
import { withStyles } from 'material-ui/styles';
// Define the CSS styles you which to apply to your component
const styles = {
root: {
backgroundColor: 'red',
},
};
class MyComponent extends React.Component {
render () {
// withStyles automatically provides the classes prop, which
// will contain the generated CSS class name that you can match
// to your component
return <div className={this.props.classes.root} />;
}
}
export default withStyles(styles)(MyComponent);
These non-deterministic class names have technical benefits, including improved performance:
Thanks to the non-deterministic nature of our class names, we can implement optimizations for development and production. They are easy to debug in development and as short as possible in production.
You should note that this happens because material-ui takes a fundamentally different approach to styling than a library like Bootstrap. While Bootstrap has a CSS library with defined class names that get applied to each element, material-ui uses CSS in JS to inject styling. This allows CSS to be defined and stored alongside the JavaScript definition of each component.

Import default react component with two or more different name

What I am trying to do:
Import the same default component twice or more times in one file. The reason of why I want to do this are because the component are the same, I only need the name difference to make it more readable.
What I have done:
import ToInput from './input';
import FromInput from './input';
Is there a correct way to do this? It works, but the ESLint is complaining about duplicate import.
import Input as MyInput from './input';
import Input as MySecondInput from './input';
Now you may use the component as MyInput or MySecondInput, as both are references or instances of the same component.
You shouldn't ever need to do this. Post the scenario as to why you need this.
Just do this:
const FromInput = ToInput;
Or just disable the eslint rule for that file if you really need it.
/* eslint-disable import/your-rule-here */
It seems like what you really want to do is create two distinct instances of an Input component, but what you have described is to create a copy of the Input component class/descriptor. While it is possible to do this, it is usually a bad practice.
Try to think about React in terms of Object Oriented concepts. Remember that the imported construct from './input' (in your case, ToInput) is a Class and not yet an Instance of that class.
Traditionally to create an instance of a class called Input, we would write something like this:
var toInput = new Input()
However, when defining an instance of the class Input in React, we typically use JSX tags:
<Input />
The above is JSX tag is an instance of Input, and NOT actually the Input class itself.
From what I gather in your question, I think the following would be a more appropriate approach that employs better patterns and practices.
Import a singular, generic Input component descriptor/class.
import Input from './input'
If readability is your ultimate goal, then perhaps differentiate the two components with a prop, rather than creating copies of the component class. You could use an id prop for example:
<Input id='to-input' />
<Input id='from-input' />
Hopefully this answers your question.

Reactjs inheritance

I'm very new to React and I'm trying to make a simple application that renders html controls.
I want to have an API that return array of json objects contains properties that determine the type and the value of each control like id, type, value ... etc.
Let's say that I have some controls like Input and Button.
What I'm thinking of is Creating a base class named HtmlControl that extends React.Component and other html controls should extend from the HtmlControl and finally a class for rendering these controls.
How can I be able to render the controls that extends only HtmlControl class ?
That would not be a good choice as react says you should not focus inheritance rather focus on containment or composition.
React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components.
and
At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies.
Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions.
Please Visit this link to learn more.
You can create separate classes for each of the components or elements and combine them in one class like this:
import Button from './Button'
import Radio from './Radio'
import TextInput from './TextInput'
class HtmlComponent{
// note: we don't need to extend it from React.Component
// we will some function to render them.
renderTextInput() { <TextInput /> }
renderRadio() { <Radio /> }
}
// you can now use below code:
const hC = new HtmlComponent();
hC.renderTextInput();
Note Again this is not a nice idea to do but you can achieve your goal.

Resources