changing an element's className doesn't work properly - javascript

I want to change the color of an element by switching className, and the className is not changing.
I am currently using nextJS and mobX.
here is the example code:
Example.tsx
<div
className = {store.isChosen ? 'isChosen' : 'isNotChosen'}
onClick={()=>{
store.isChosen = !store.isChosen;
}}
>ELEMENT</div>
// this doesn't work either
<div
className = {store.isChosen ? `{styles.isChosen}` : {styles.isNotChosen}`}
onClick={()=>{
store.isChosen = !store.isChosen;
}}
>ELEMENT</div>
ExampleStore.ts
#observable
isChosen:boolean = false;
Example.module.scss
.isChosen{
background-color: red;
}
.isNotChosen{
background-color: blue;
}

An observable in Mobx is, as its name suggest, observed for any change that can affect it, that's why when you just set the value to something new, it directly reflected. You can even create an observable object and update the values inside like : myState.stateKey = "new Value" and it would work too thanks to Proxy.
I invite you to read docs for more infos.

Related

Can react simply change CSS style by selector that's defined elsewhere

To start, I am working with react-swipe-to-delete-component, but I feel that should make little difference in the question.
I am trying to change the background-color property of a "built out" element. I have no control over the class name as the plugin uses it, and I cannot assign it (I think) a separate class name as it stands. Is there a way to change the style of a element solely based on selector, like in vanilla JavaScript?
I have this element <SwipeToDelete>. It builds out a div that I need to access by the selector:
<div class="swipe-to-delete">
<div class="js-delete">
And thus I need to be able to access
.swipe-to-delete .js-delete
as a selector.
Is there a way like in JS IE document.getElementsByClassName('.swipe-to-delete .js-delete')[0].style.background-color = "#FFF")
I need to change the background color based on which function is called:
const [isRight, setRight] = useState(false);
const [isLeft, setLeft] = useState(false);
const onLeft = (...args) => {
// Make Mask Red with Icon
console.log('Set left to true');
setLeft(true);
}
const onRight = (...args) => {
// Make Mask Green with icon
console.log('Set right to true');
setRight(true);
}
<SwipeToDelete
onLeft={onLeft}
onRight={onRight}
>
This works.. I just don't know how to incorporate this pseudo statement
isRight ? '.swipe-to-delete .js-delete'.backgroundColor="green" : ''
Since I can't access <SwipeToDelete>'s inner workings to set a class name somewhere, without modifying the node-module code. I really am stuck here.
I just want to simply change the background color of .swipe-to-delete .js-delete depending on right or left function. Am I looking at this the wrong way?
There is a classNameTag prop you can use to define a className on the wrapper element for <SwipeToDelete> (the element with className="swipe-to-delete").
Based on the swipe direction you set the className accordingly:
<SwipeToDelete
classNameTag={isRight ? "is-right" : isLeft ? "is-left" : ""}
onLeft={onLeft}
onRight={onRight}
>
And styling with CSS:
.swipe-to-delete.is-right .js-delete {
background-color: green;
}
.swipe-to-delete.is-left .js-delete {
background-color: red;
}

Replace class using javascript is not working in reactjs

I want to change the class of dynamic element on click function for that I tried below solutions but none of these working
handleClick=(event,headerText)=>{
document.getElementsByClassName('sk-reset-filters')[0].className = 'jjjj';
}
handleClick=(event,headerText)=>{
var reset = document.querySelectorAll('.sk-reset-filters.is-disabled')[0];
console.log(reset)
if(reset){
reset.className = 'sk-reset-filters';
console.log(reset)
}
I just want to remove the is-disabled when click. I also tried using setTimout function but doesn't work. Is there anything wrong?
When I console.log(reset) I'm getting below html.
<div class="sk-reset-filters is-disabled">
<div class="sk-reset-filters__reset">Clear all</div>
</div>
You can handle disable or show dom elements with react state in this way:
state={isDisabled:true} // set a state property
handleClick=(e)=>{
e.preventDefault
this.setState({isDisabled:false}) //change !isDisabled to false when clicked
}
render() {
{isDisabled} = this.state
let disabledMarkup = isDisabled ? <div>something</div> : null}
return (<React.Fragment>{disabledMarkup}
<button onClick={this.handleClick}></button>
</React.Fragment>)}

change color according to class with SASS condition

I am creating cards and I want them to have different color according to their type (angel, demon, etc.) The type is a condition in my JS file according to my database.
I am using SASS and I'm lost !
I tried something like this but it doesn't work at all, any idea ?
.card{
#if .demon{
background-color: yellowgreen;
}
#if .angel{
background-color: aqua;
}
}
I want the all card to change not just where the type appear,
Any help is welcomed thanks in advance !
Welcome Nao,
Supposing we have a flag comming from the API called cssClass: string string is the angel or demon value which came from the API.
then, in our class, at the render method, we can get the cssClass value after we have stored it in the class's state as follows:
const { cssClass } = this.state
supposing we have a Card component that will be rendered when that value changes, we can do this to listen to the cssClass value changes and give a proper className depending on it.
In render method we have this:
render(){
const { cssClass } = this.state;
return(
<Card className={`card ${cssClass.length ? cssClass : ''}} />
)
}
In here: className={card ${cssClass.length ? cssClass : ''}}`
we are asking the cssClass attribute if it holds any length of a string that is greater than 0 as a value, if true, return that value, which could be demon or angel, else, it will return an empty string.
in your css file you'll not need any #if flags, just do the css regularly.
You can use parent selector:
.card{
.demon &{
background-color: yellowgreen;
}
.angel &{
background-color: aqua;
}
}

How do I style a div inside a component without passing props to that component (I'm using a package)

I'm using the react-scrollbar package to render a scrollbar for my my content. What I also want is a arrow button that, on click, moves to a certain scrollbar area. The problem is, I'm trying to style (marginTop) a class inside my component.
This is my attempt:
// MY COMPONENT
scrollToNextUpload = () => {
const NextUpload = 400
this.setState({ marginTop : this.state.marginTop + NextUpload }, () => document.getElementsByClassName('scrollarea-content')[0].style.marginTop = "'" + this.state.marginTop + "px'")
}
// MY RENDER
render () {
<ScrollArea>
// my content
<div onClick={this.scrollToNext}></div>
</ScrollArea>
}
What is actually rendered
<div class='scrollarea'>
<div class='scrollarea-content'>
// my content
<div onClick={this.scrollToNext}></div>
</div>
</div>
What I want
To make my area with the scrollbar scroll, I have to add a marginTop style to the 'scrollarea-content'. I could do this by passing props to the < ScrollArea > and then use them inside the installed package; but I'm trying to avoid altering the original package content.Also, is there another way how I could scroll by click and is there someone else who's experienced with that NPM Package?
Most libraries give props to apply style to child components, in this library you can pass a className to the contentClassName or use inline style in contentStyle prop :
<ScrollArea contentStyle={{ marginTop: 10 }}>
An another way is to write css to add style to the scrollarea-content class.
In a .css file :
.scrollarea-content {
margin-top: 10px;
}
Edit: In your case you can programatically change the marginTop style by using the props like this :
scrollToNextUpload = () => {
const NextUpload = 400;
this.setState(prevState => ({ marginTop : prevState.marginTop + NextUpload }));
}
render () {
<ScrollArea contentStyle={{ marginTop: this.state.marginTop }}>
// my content
<div onClick={this.scrollToNext}></div>
</ScrollArea>
}
Note the use of a functional setState to prevent inconsistencies when next state value depends on the previous state.

Reactjs: How to get a css-class attribute from a mounted <div>?

Lets say I have a react DOM element like this one:
render () {
...
return (
<div className = "widePaddingRight" style = {{width: "100px"}}
ref = "pickMe"
>
...
</div>
)
}
CSS:
.widePaddingRight{
paddingRight: 20px
}
If I access this element later and try to get its width like that:
componentDidMount () {
var elem = this.refs.pickMe.getDOMNode().getBoundingClientRect()
console.log(elem.width)
}
I get 120 in my console. My expected result was 100. Since I have to calculate with the original width I have to get the padding-attributes of the element.
Question: How can I get the paddingRight attribute of my component in my react-class?
Update
With the input of #Mike 'Pomax' Kamermans I was able to solve the underlying problem (thank you for that): Just add box-sizing: border-box to the CSS. Now getBoundingClientRect() gives 100 instead of 120.
I still dont know how to get a css class-attribute from a mounted div - any suggestions?
You need window.getComputedStyle.
const style = window.getComputedStyle(React.findDOMNode(this.refs.pickMe));

Categories