Get a JSX's elements class name after load and on change - reactjs

I'm a bit lost learning React here.
I'm trying to get the class name of an element so I can inject an inline color depending on that class name. For example, if the element below has the class 'Active'.
<li className="active" >
I was experimenting trying to use the onChange event to see if it worked but I can't seem to fetch and print anything in the console. I assumed the event would have triggered after load and when the clase name changes, doesn't seem the case.
<li className="active" onChange={(e)=> {(console.log(e.target.className))}}
I've read a bit about React refs but it seems too much for such a simple thing. What am I missing here?

You don't need to use onChange event. You probably want to use the document object wherever you want to change the style of an element.
document.getElementsByClassName("Active")[0].style.color = '#fff';
You can use it in a function and trigger it wherever you want, or just simply put it inside useEffect hook to execute on component mount.

Related

Pass classname to material ui date-picker dialog

Is there a way to pass classname to matererial-ui datepicker's dialog.
http://www.material-ui.com/#/components/date-picker
Material-ui's datepicker accepts classname as a prop. But, this gets applied to the text-field upon which we want to trigger the date-dialog.
I want to pass a class attribute to the date-popup itself. Something like:
dialogClassName
The need is I want to access if the click was done somewhere inside the date-dialog and manage some other part of my code based on that. I can't figure out how to make the date-dialog accept a classname.
This issue was a bit boosting,https://github.com/mui-org/material-ui/issues/5329 but passing a dialogClassName doesn't get applied.
There is a solution which I came across by going through the DatePicker Code. You can pass the following props to the DatePicker
<DatePicker>
PopperProps={{
className: classes.desktopView,
}}
DialogProps={{
className: classes.mobileView,
}}
</DatePicker>
I'm afraid you cannot do that without modifying the DatePicket component ( at least not without some wild hacks).
If you really need this functionality you can fork material-ui repository, make the changes and submit a pull request. Or, in you project, create a local DatePicker component and do the changes there, but this approach requires you to update your version in case material-ui's version is updated.
There is no solution as of yet. However there is a workaround to pass a css class name to popup/dialog container.
Pass an img tag for rightArrowIcon props of datepicker with onload function to call its parent and inject css class.
<DatePicker
disableToolbar={true}
variant="inline"
inputVariant="outlined"
rightArrowIcon={<img src="/images/chevron-right_1.svg" id="datepicker-arrow-right" onLoad={injectTheme}/>}
leftArrowIcon={<img src="/images/chevron-right_1.svg" style={{transform:"rotate(180deg)"}}/>}
....
....
....
/>
const injectTheme=()=>{
let node = document.getElementById("datepicker-arrow-right").parentNode.parentNode.parentNode.parentNode.parentNode.parentElement;
node.classList.add("Css-Class-Name");
}

react willReceiveProps workaround for external library

I'm using a react datepicker component that can be found here. The component is pretty great except for what appears to be an oversight: it does not implement willReceiveProps.
To expound, I create the datpicker as below:
<DateField
dateFormat= { dateFormat}
forceValidDate={true}
defaultValue={startDate || ''}
onChange={this.handleChange.bind(null, 'start_date')}
id="start"
>
<DatePicker
navigation={true}
locale="en"
forceValidDate={true}
highlightWeekends={true}
highlightToday={true}
weekNumbers={true}
weekStartDay={0}
/>
</DateField>
Note above that there is a prop defaultValue which I pass startDate. Now, startDate can and does change for reasons that are sometimes external to the component. That value is passed during a new render() action as per usual. According to react philosophy this shouldn't be a problem.
However, it appears to me as if the value from defaultValue is only ever read once inside DateField. It is read as this.props.defaultValue. Anyone who has ever built a component relying on props should quickly recognize this is a problem. It means that when the prop is changed the new value will not be used.
Because this is a library, I cannot simply implement willReceiveProps. Does anyone know of a good workaround to get this component to either completely reset on a render or some other strategy to deal with what seems to be a big design problem?
They follow the same standards as the <input> component. defaultValue is read only once but there is also value that can be set externally. There is no need for them to use willReceiveProps.
In short, use value instead of defaultValue.
See Uncontrolled Components in React
PS: I am looking a bit into the code and it seems there are also properties text and date apart from value. Since the code (and documentation) has been removed from github, I won't inspect what is the difference between those props.

How to envoke a method on a react component (Amcharts-React)

Is there a way to evoke a method on a chart. Such as:
chart.zoomOut()
I'm struggling to find a handle for the chart object.
To render the chart i use:
<AmCharts ref={`chart_${this.props.tileid}`} {...this.chart} dataProvider={this.props.data} />
https://github.com/amcharts/amcharts3-react
I tried to inspect the element to see if I can access these methods through:
ch = this.refs[`chart_${this.props.tileid}`]
However in the 'ch' object I can not seem to find any of the methods mentioned in:
https://docs.amcharts.com/3/javascriptcharts/AmSerialChart#zoomOut
How would one reference a element to evoke a method on it?
The amchart3-react component sets the chart as a state. Thus the method can be evoked by calling:
this.refs.chartref.state.chart.zoomOut();
You will have to talk to the maintainers of amCharts3-react. The wrapper component library could have defined the component to accept as property an event-handler that is called when the wrapper's componentDidMount method has been called, so that the event-handler can grab an instance of an object that the wrapper component is a container of.
Example:
// Note, this is just a hypothetical property. It will not actually do anything
// when applied to your code.
<AmCharts onChartRendered={chart => this._amChart = chart } {...props} />
But it seems like the author of the wrapper did not define the component to accept any such property, and therefore there isn't any way for you to invoke any methods from amCharts.

ReactJS: Easily access state objects from data-reactid attributes?

I'm working on my first react app. I noticed that the state that contributes to an element is occasionally reflected in the reactid. Maybe it's the key that was passed?
I can't find a lot of documentation on reactid but I was wondering if there was a good way to isolate those keys.
for example, an element that I'd like to update has the ID: .0.1.0.1.$4.3:$level.1
The $ represent known indices of the state object I used to build that DOM node. (specifically, this is the object this.state.figures[4].level)
It would be really awesome if I could parse those $ values out with a predefined method, to make it easy to setState. Does such a thing exist?
This is me trying to setState on events defined by the top ancestor to avoid cumbersome bidirectional event handling. Am I being really foolish with my approach?
if I understand correctly you're looking to bind events to DOM nodes based on their data-reactid's?
If so - I don't think that's a wise idea at all. The data-reactid property is qutie transient, it changes without warning and is influenced by a number of events in the React ecosystem.
I like to think of DOM generated by React as a compile target, something I'm not really even supposed to interact with at all. A black box, if you will.
If you need help solving an eventing issue, you may want to describe that itself.
EDIT
You can add event handlers in React which are aware of their position in an iterator, and aware of the current state of the component.
<div>
{
things.map((thing, index) => {
return (
<li
className="level"
key={`level_${index}`}
onClick={this.handleClick.bind(this, thing)}>
{ thing }
</li>
);
});
}
</div>
So handleClick would receive the thing item when clicked, which could give you information about that particular thing. You could pass the index too. In handleClick you'll also have access to this.state.

AngularDart: Component attribute

I'm new to Angular and I have the following problem.
I'm trying to create a component that can be active. I currently set it up so it detects if an attribute called active exists and sets its internal state accordingly.
<page active page-id="page-1"></page>
The problem emerged when I wanted to remove the active state. How should I go about it? Should I switch to css classes? Or maybe use a directive?
This seems a little 'hacky' but, first you need to get the element somehow and access the attribute Map directly and just remove it like,
HTML
<page active page-id="page-1" id="page_one"></page>
Dart
querySelector('#page_one').attributes.remove("active");
https://api.dartlang.org/apidocs/channels/be/dartdoc-viewer/dart:html.Element#id_attributes

Resources