Styled-JSX variables not working - reactjs

I have installed styled-jsx using styled-jsx#2.2.6 and am doing something like so:
import React, { Component } from 'react'
export default Index class extends Component {
constructor(props){
super(props)
this.state = { clicked: false}
}
render(){
return(){
<div>
<button onClick={() => this.setState({clicked: !this.state.clicked}}}>Hello</button>
<style jsx>{`
button {
background-color: ${this.state.clicked ? 'red' : 'blue'}
}
`}<style>
}
}
}
No styles what so ever are being applied and I console logged out the clicked state and it is being changed.

Here's working example. You had lot of typo's in there. I assume you are not using appropriate IDE that usually points out at all those issues.
Here's the working code: https://stackblitz.com/edit/react-3ttfch
Here's your fixed typoless code:
class Index extends Component {
constructor(props) {
super(props)
this.state = { clicked: false }
}
render() {
return (
<div>
<button onClick={() => this.setState({ clicked: !this.state.clicked })}>
Hello
</button>
<style jsx>{`
button {
background-color: ${this.state.clicked ? 'red' : 'blue'}
}
`}</style>
</div>
);
}
}

Related

Show/ Hide a div according to toggle Switch on/off

I want to display/hide the chat body when on/off the switch. That means when switch on I want to display the chat body and when to switch off I want to hide it. Below is an image of toggle switch that I have used. Can you give me help to do that?
class MyApp extends Component {
render() {
return (
<FormControlLabel
control=
{
<Switch
name="sector"
color="primary"
style={{paddingRight: "30px"}}
onClick={this.handleClick.bind(this)}
/>
}
label="Sector 1"
/>
<div className="chatBody">
This is my chat body
</div>
);
}
}
export default MyApp;
You can show/hide the div content using the React state handlers, your code then could look like this:
class MyApp extends Component {
constructor(props) {
super(props);
this.state = {showBody: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick () {
// toggle the showBody state to hide and show the body
this.setState({ showBody: !this.state.showBody })
}
render() {
return (
<FormControlLabel
control=
{
<Switch
name="sector"
color="primary"
style={{paddingRight: "30px"}}
onClick={this.handleClick}
/>
}
label="Sector 1"
/>
{this.state.showBody && (
<div className="chatBody">
This is my chat body
</div>
)}
);
}
}
export default MyApp;
As you can see on the this.state.showBody && we are declaring that the body should only display if the showBody state is true.
Then in some scenarios for "controlled inputs" there is probably a property in your Switch for the "checked" state (it usually depends on the library) and then you can use the state in the Switch to a controlled value: checked={this.state.showBody}.
Just add a state to control this:
class MyApp extends Component {
constructor(props) {
super(props);
this.state = {
checked1: false,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
this.setState({
checked1: e.target.checked,
});
}
render() {
return (
<>
<FormControlLabel
control={
<Switch
checked={this.state.checked1}
name="sector"
color="primary"
style={{ paddingRight: "30px" }}
onClick={this.handleClick.bind(this)}
/>
}
label="Sector 1"
/>
{this.state.checked1 && <div className="chatBody">This is my chat body</div>}
</>
);
}
}
export default MyApp;

React, problem with passing state as props

So I am quite new to React world, and I have this problem I am trying to solve, but I don't quite understand why it is happening.
So I want to pass the state of component to parent component and from parent component to child component and everything look okay, and in console log the state goes trough, but nothing changes. I believe there is a way I need to listen for state change or something within child component so it works. If I put true in the parent component, child component also get's true, but if I toggle it on click, it goes trough but nothing changes in the child component.
Also I understand my code is little rough right now ill reafactor it later, but right now I am trying to understand why it does not work.
If anyone could help me I would be thankful for it.
This is component that controls the state.. So the state passes from TurnOnBtn to App and from App it goes to TodoList
import "./Todo.css";
class TurnOnBtn extends Component {
constructor(props) {
super(props);
this.state = { display: false };
this.handleState = this.handleState.bind(this);
}
handleState() {
this.setState({ display: !this.state.display });
this.props.checkDisplay(this.state.display);
}
render() {
return (
<button onClick={this.handleState} className="TurnOnBtn">
<i className="fa fa-power-off"></i>
</button>
);
}
}
export default TurnOnBtn;
parent component App
import TurnOnBtn from "./TurnOnBtn";
import TheMatrix from "./TheMatrxHasYou";
import TodoList from "./TodoList";
import { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = { display: true };
this.checkDisplay = this.checkDisplay.bind(this);
}
checkDisplay(newDisplay) {
this.setState({
display: newDisplay,
});
console.log(this.state);
}
render() {
return (
<div className="App">
<TodoList display={this.state.display} />
<TheMatrix />
<TurnOnBtn checkDisplay={this.checkDisplay} />
</div>
);
}
}
export default App;
child component TodoList
import Todo from "./Todo";
import NewTodoForm from "./NewTodoForm";
import { v4 as uuid } from "uuid";
import "./Todo.css";
class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
todos: [],
displayOn: this.props.display,
};
this.newTodo = this.newTodo.bind(this);
this.editTodo = this.editTodo.bind(this);
this.deleteTodo = this.deleteTodo.bind(this);
}
editTodo(id, updatedTask) {
const updatedTodo = this.state.todos.map((todo) => {
if (todo.id === id) {
return { ...todo, todo: updatedTask };
}
return todo;
});
this.setState({
todos: updatedTodo,
});
console.log(updatedTask);
}
deleteTodo(id) {
this.setState({
todos: this.state.todos.filter((todo) => todo.id !== id),
});
}
newTodo(newState) {
this.setState({
todos: [...this.state.todos, { ...newState }],
});
}
render() {
return (
<div
style={this.state.displayOn ? { opacity: 1 } : { opacity: 0 }}
className="Todo-screen"
>
{" "}
<div className="TodoList">
<div className="TodoList-todos">
{" "}
{this.state.todos.map((todo) => (
<Todo
key={uuid()}
id={todo.id}
active={todo.active}
editTodo={this.editTodo}
deleteTodo={this.deleteTodo}
todoItem={todo.todo}
/>
))}
</div>
</div>{" "}
<NewTodoForm newTodo={this.newTodo} />
</div>
);
}
}
export default TodoList;
The bug here is in these line of codes:
handleState() {
this.setState({ display: !this.state.display });
this.props.checkDisplay(this.state.display);
}
Remember setState is an async function, so by the time you set a new state using setState, the value for this.state is not guaranteed changed.
One way to fix this is using the setState callback, which will run after the state is changed:
handleState() {
this.setState({ display: !this.state.display }, function() {
this.props.checkDisplay(this.state.display);
});
}
But you don't need to use another state to keep display state in TurnOnBtn as you can pass the toggle callback from the parent:
App.js
class App extends Component {
constructor(props) {
super(props);
this.state = { display: true };
this.toggleDisplay = this.toggleDisplay.bind(this);
}
toggleDisplay() {
this.setState({
display: !this.state.display,
});
}
render() {
return (
<div className="App">
<TodoList display={this.state.display} />
<TheMatrix />
<TurnOnBtn toggleDisplay={this.toggleDisplay} />
</div>
);
}
}
TurnOnBtn.js
class TurnOnBtn extends Component {
constructor(props) {
super(props);
this.handleState = this.handleState.bind(this);
}
handleState() {
this.props.toggleDisplay();
}
render() {
return (
<button onClick={this.handleState} className="TurnOnBtn">
<i className="fa fa-power-off"></i>
</button>
);
}
}

open a html modal programmatically in React

I have this two elements a button and a dialog
<dialog className='w-11/12 shadow-none rounded-tl-md rounded-tr-md lg:rounded-lg absolute'>wqdwe</dialog>
<button className=" px-6 py-2 rounded absolute mt-12 ml-12" onClick={} >Click</button>
How can I open the dialog on clicking the button in React
constructor(props) {
super(props);
this.myRef = React.createRef();
}
showModals(){
this.myRef.showModal();
}
componentDidMount() {
//this.showModals()
}
EDIT: I am trying to access the .showModal() method in the dialog according to MDN https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog. How can I do that, I need the dimmed background feature when the modal is opened.
You do not need componentDidMount nor useRef with the state and using the props open of the dialog you can show it conditionally.
first solution using isOpen is the state
class Modal extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<dialog style={{width: "80%", height: "80%", marginTop: 10, backgroundColor: '#eee'}}
open={this.props.open}
>
<p>Greetings, one and all!</p>
</dialog>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
isOpen: false
};
}
switchModal = (prevState) => {
this.setState((prevState, props) => {
return { isOpen: !prevState.isOpen }
});
}
render() {
return (
<div>
<button onClick={this.switchModal}>
{this.state.isOpen ? 'Close' : 'Open'} Modal
</button>
<br/>
<Modal open={this.state.isOpen}/>
</div>
);
}
}
React.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js"></script>
<div id="root"></div>
second solution using native showModal method. With this method you can use the css property dialog::backdrop.
class Modal extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<dialog id='modal' style={{width: "80%", height: "80%", marginTop: 10, backgroundColor: '#eee'}}
>
<p>Greetings, one and all!</p>
<button onClick={this.props.closeModal}>
Close Modal
</button>
</dialog>
);
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
isOpen: false
};
}
switchModal = (prevState) => {
this.setState((prevState, props) => {
if(!prevState.isOpen) {
document.getElementById('modal').showModal()
} else {
document.getElementById('modal').close()
}
return { isOpen: !prevState.isOpen }
});
}
render() {
return (
<div>
{!this.state.isOpen && <button onClick={this.switchModal}>
Open Modal
</button>}
<br/>
<Modal
closeModal={this.switchModal}
/>
</div>
);
}
}
React.render(<App />, document.getElementById('root'));
dialog {
height: 80%;
width: 80%
}
dialog::backdrop {
background: rgba(255,0,0,.25);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js"></script>
<div id="root"></div>
You can use the React state API to show and hide components based on actions taken elsewhere in the code.
class MyComponent extends React.Component {
constructor() {
this.state = {
isDialogVisible: false
}
}
handleClick = () => {
this.setState({ isDialogVisible: !this.state.isDialogVisible })
}
render() {
const { isDialogVisible } = this.state
return (
<div>
<Button onClick={this.handleClick}>{isDialogVisible ? 'Hide' : 'Show'} dialog</Button>
{this.state.isDialogVisible && <Dialog />}
</div>
)
}
}

How to toggle class of a div element by clicking on button in react js?

I want to toggleclass name of one element by clicking on another element. Both elements are in separate component files. I don't know how to get the state of an element and pass it to another element. Please help me solving the problem.
file1.js
<Button onClick={this.toggleFunction}>Button</Button>
file2.js
<div class="wrapper"></div>
I want to toggle class active on wrapper div when the button is clicked.
Thanks
class MyComponent extends Component {
constructor(props) {
super(props);
this.addActiveClass= this.addActiveClass.bind(this);
this.state = {
active: false,
};
}
toggleClass() {
const currentState = this.state.active;
this.setState({ active: !currentState });
};
render() {
return (
<div
className={this.state.active ? 'your_className': null}
onClick={this.toggleClass}
>
<p>{this.props.text}</p>
</div>
)
}
}
Parent Component
import React from "react";
import ButtonComponent from "./buttonComponent";
import "./demo.css";
//Parent Component
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false
};
}
updateValue = value => {
this.setState({
active: value
});
};
render() {
return (
<div>
<ButtonComponent updateParent={this.updateValue} />
<div
className={
this.state.active ? "dropdownbutton1" : "dropdownbutton1Active"
}
>
<label>First</label>
<br />
<select>
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
</div>
);
}
}
export default Demo;
Child Component
import React from "react";
import ToggleButton from "react-toggle-button";
import "./demo.css";
class ButtonComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false,
defaultValue: 1
};
}
togglebutton = () => {
this.props.updateParent(this.state.active);
this.setState({ active: !this.state.active });
if (this.state.active) {
this.setState({ defaultValue: 1 });
} else {
this.setState({ defaultValue: -1 });
}
};
render() {
return (
<div>
<div className="ToggleButton">
<ToggleButton onClick={this.togglebutton} value={this.state.active} />
</div>
</div>
);
}
}
export default ButtonComponent;
Link :https://codesandbox.io/s/m4py2y97zp

checkbox toggle doesn't work correctly react native

I have this checkbox example
constructor(props) {
super(props);
this.state = {
check: true,
};}
checkBoxtTest(){
this.setState(
{check:!this.state.check})}
on return
<CheckBox
value={this.state.check} onChangee={()=>this.checkBoxtTest()}
/>
when i press again in checkbox the value doesn't change
you are having a typo 'onChange'
<CheckBox
value={this.state.check} onChange={()=>this.checkBoxtTest()}
/>
If you are using state for changing state follow this way
this.setState((prevState) => ({check: !prevState.check}))
You can use arrow function instead of normal function
checkBoxtTest = () => {
this.setState((prevState) => ({check: !prevState.check}));
}
import React, { Component } from 'react';
import { Container, Content, ListItem, CheckBox, Text, Body } from 'native-base';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
checked: true
}
}
render() {
return (
<Container>
<Content>
<ListItem>
<CheckBox
checked={this.state.checked}
onPress={() => this.setState({checked: !this.state.checked})}
/>
<Body>
<Text>Finish list Screen</Text>
</Body>
</ListItem>
</Content>
</Container>
);
}
}
Firstly,change it to onChange.And your checkBoxTest should be bind in the constructor as it is recommended as best practice.
constructor(props) {
super(props);
this.state = {
check: true,
};
this.checkBoxtTest = this.checkBoxtTest.bind(this);
}
checkBoxtTest(){
this.setState({
check : !this.state.check
})
}
<CheckBox value={this.state.check} onChange={this.checkBoxtTest()} />

Resources