React - How to convert a simple function to a class? - javascript

How do I convert this code into a class component? the problem is const {value} = useDarkMode (false); I don't understand how to apply it in a class component
import './Content.css'
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
}

Try something like this
import './Content.css'
import React from 'react';
import useDarkMode from 'use-dark-mode';
export default function Content () {
const { value } = useDarkMode(false);
return <MyContent value={value} />
}
class MyContent extends React.component{
render() {
return <div>
<div className={this.props.value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>;
}
}

You can't use hooks in class component. If you want to use useDarkMode, change your component class to functional component like this:
export const Content = () => {
const { value } = useDarkMode(false);
return (
<div>
<div className={value ? 'Dark_Mode' : 'Light_Mode'}>
<h3>Hello from React.JS</h3>
</div>
</div>
)
}

Related

Why isn't the component child rendered?

I have written the following code in APP.js component:
import React from "react";
import Exam from "./exam.js";
export default function App() {
return (
<Exam>
<h1>hashemi</h1>
</Exam>
);
}
And I have written the following code in exam.js component:
import React from "react";
const Exam = ({child}) => {
return (
<div>
<p>parastoo</p>
{child}
</div>
);
};
export default Exam;
But the output shows this:
parastoo
What is the problem? Why doesn't the child <h1> render?
Child components are passes via the children prop to the component, even if there is only a single child:
const Exam = ({children}) => {
return (
<div>
<p>parastoo</p>
{children}
</div>
);
};
It's called props.children. Read from the documentation section Containment.
const Exam = (props) => {
return (
<div>
<p>parastoo</p>
{props.children}
</div>
);
};
I hope this helps!
In React, you can pass props, or properties, to child components. Say you have an App component which renders a child component called CurrentDate which is a stateless functional component. You can pass CurrentDate a date property by writing:
const CurrentDate = (props) => {
return (
<div>
{ /* change code below this line */ }
<p>The current date is: {props.date} </p>
{ /* change code above this line */ }
</div>
);
};
Calender is a parent Component, you can pass Calender a date property by writing
class Calendar extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<h3>What date is it?</h3>
{ /* change code below this line */ }
<CurrentDate date={Date()}/>
{ /* change code above this line */ }
</div>
);
}
};

Component not re-rendering when dictionary value changes

Simple: I change a dictionary value and the component is not re-rendering. The value actually changes when I log it, it just doesn't render on the screen.
This is where it's happening. The Icon should change from 'caret-down' to 'caret-right' but for some reason it's not:
import React, {Component} from 'react';
import {inject,observer} from 'mobx-react';
#inject("appStore") #observer
class Attribute extends Component {
...
toggleValueDisplay = (attr) => {
node.attributeToggle[attr] = !node.attributeToggle[attr];
};
render() {
...
const { node, attr } = this.props;
let vals = node.attributes.get(attr);
return (
<div>
<span>
<div>{attr}</div>
<Icon type={node.attributeToggle[attr] ? "caret-down" : "caret-right"} onClick={(attr) => {this.toggleValueDisplay(attr)}}/>
</span>
...
</div>
)
}
}
export default Attribute;
This is where the Attribute component is being rendered:
import React, {Component} from 'react';
import {inject,observer} from 'mobx-react';
import Attribute from "./attribute";
#inject("appStore") #observer
class Tab extends Component {
...
render() {
let node = this.props.appStore.repo.canvas.currentNode;
return (
<div className="tab-body">
{/* ATTRIBUTES */}
{
<div>
<h5>Attributes</h5>
{
[...node.attributes.keys()].map((attr) => {
return <Attribute node={node} attr={attr} key={attr}/>
})
}
</div>
}
</div>
);
}
}
export default Tab;
This is the Node object, for reference
import {observable} from 'mobx';
export default class Node {
id = '';
...
#observable attributes = new Map(); // {attribute : [values]}
#observable attributeToggle = {}; // {attribute : bool}
constructor(r) {
for (let property in r) {
this.attributes.set(property, r[property]);
this.attributeToggle[property] = false;
}
}
}
========================= THINGS I HAVE TRIED =========================
I've tried changing this:
{
node.attributeToggle[attr] ?
<Icon type="caret-down" onClick={(attr) => {this.toggleValueDisplay(attr)}}/>
:
<Icon type="caret-down" onClick={(attr) => {this.toggleValueDisplay(attr)}}/>
}
and also this where the Attribute component is used in Tab
{/* ATTRIBUTES */}
{
<div>
<h5 >Attributes</h5>
{
[...node.attributes.keys()].map((attr) => {
return <Attribute node={this.props.appStore.repo.canvas.currentNode} attr={attr} key={attr}/>
})
}
</div>
}
but it doesn't work. Not sure why this isn't working please help :)
You are using props which are not mutable use state instead
You don't trigger the component render anywhere, so of course it doesn't update. You can do it manually like this:
toggleValueDisplay = (attr) => {
node.attributeToggle[attr] = !node.attributeToggle[attr];
this.forceUpdate()
};

How to get label values dynamically and adding the numbers together from different input with reactjs

Created a Div and inside it I have label element and input element, I want to get different label values in each div. How to re-use my div component
instead of coding the same code again.
I have tried to search in Stackoverflow plus googles, Haven't received a better answer.
Here I have created div element with just label and input element and then I have rendured this component in App.js file:
How can I reuse the same code/component to create 2 more div and having different labels values in it? Ho can I add numbers together from different input ( which I am getting from different components input)
Appreciate all your help!
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
state = {
inputOne: '',
inputtwo: '',
inputthree: ''
}
getInputValue = (e) => {
const value = e.target.value;
console.log('value: ', value);
this.setState({
inputOne: Number(e.target.value)
});
}
render() {
const { value } = this.props // destructuring
const {inputOne, inputtwo, inputthree } = this.state
return (
<div className="boxes">
<label className="boxeslevel" htmlFor="text">
{value}
</label>
<input
name="text"
type="text"
onChange={this.getInputValue}
/>
</div>
);
}
}
export default Boxes;
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="wrapper">
<Boxes value= {"Value 1:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 2:"} onChange={this.props.onChange}/>
<Boxes value= {"Value 3:"} onChange={this.props.onChange}/>
<ShowResult />
</div>
);
}
}
export default App;
You should pass a prop to your componente to be reuse. As you notice you are using local component state in your component, like const {value} = this.state try the same approach but with props like const {value} = this.props and then passing that prop in the component usage like
<Boxes value={“label 1”}/>
<Boxes value={“label 2”}/>
That would work. Hope it help you
Remember you can use as many props you need and access them as the same way mention above
You can do something like this:
class Boxes extends Component {
render() {
const { value } = this.props // value coming from props
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;
and in your app component something like this:
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={1}/>
<Boxes value={2}/>
<Boxes value={3}/>
</div>
);
}
}
export default App;
Here is live demo link
You have to use props instead of state in your Boxes component. Then you can pass the required props from the App component.
App.js
import React, { Component } from 'react';
import './App.css';
import Boxes from './components/calculator';
class App extends Component {
render(){
return (
<div className="App">
<Boxes value={"Value 1"}/>
<Boxes value={"Value 2"}/>
<Boxes value={"Value 3"}/>
</div>
);
}
}
export default App;
Boxes.js
import React, { Component } from 'react';
import './calculator.css';
class Boxes extends Component {
render() {
const { value } = this.props // destructuring
return (
<div className="wrapper">
<div className="firstBox">
<label htmlFor="text">
{value}
</label>
<input name="text" type="text" />
</div>
</div >
);
}
}
export default Boxes;

ReactJS How to pass child component values to parent component

I have below codes
chat.js
import React from 'react';
import '../styles/Chat.css';
import Web from '../services/Web';
class Chat extends React.Component {
constructor(props) {
super(props);
this.state = {
msg:''
};
this.sendMessage = this.sendMessage.bind(this);
}
sendMessage () {
this.props.updatecommentText(this.refs.newText.value, this.props.index);
this.setState({ msg: '' });
}
render() {
return (
<div className="Chat-container">
<div className="Chat-row">
<div className="Chat-column">
<div className="Chat-card">
<div className="Chat-body">
<div className="Chat-title">React Based Chatbot</div>
<div className="Chat-messages">
{ this.props.children }
</div>
</div>
<div className="Chat-footer">
<textarea className="Chat-input" ref="newText"></textarea>
<button className="Chat-submit" onClick={this.sendMessage} defaultValue={ this.props.children }>Send</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Chat;
Web.js
import React, { Component } from 'react';
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import Chat from '../components/Chat';
class Web extends React.Component {
constructor(props){
super(props);
this.state = {
messages:["Hi, How can I help you ?"
]
};
this.sendtobot = this.sendtobot.bind(this);
}
sendtobot(newText, i){
var arr = this.state.messages
arr.push(newText)
this.setState({messages: arr})
}
eachMessage(message, i){
return (<Chat key={i} index={i} updatecommentText={ this.sendtobot.bind(this) }>{ message }</Chat>);
}
render(){
return(
<div>
{this.state.messages.map(this.eachMessage.bind(this))}
</div>
)
}
}
export default Web;
I wanted to take the input from the Chat.js and send it to Web.js and push that value to array messages and then again render that array in the this.props.children in Chat.js
But, while running the code, I am getting an error this.props.updatecommentText is not a function.
Can someone please help me with this.
You have bind this.sendtobot twice. It should be only in the constructor.
like this
eachMessage(message, i){
return (
<Chat key={i} index={i} updatecommentText={this.sendtobot}>
{ message }
</Chat>
);
}
Your code seems to work.
Here is a sandbox with your code.
I'm not sure it works as you would expect, but it works without errors.
By changing this 3 functions in Web component, it starting to look like a chat with only one textarea
sendtobot(newText, i) {
this.setState({ messages: [...this.state.messages, newText] })
}
eachMessage(message, i) {
return (<p>{message}</p>);
}
render() {
return (
<div>
{this.state.messages.map(this.eachMessage.bind(this))}
<Chat updatecommentText={this.sendtobot}/>
</div>
)
}
You can pass child's component state to parent component using redux also as global state.

Insert Props in a React class component

I'm working with ReactJS and the npm module "react-media-query-hoc", everything is fine when I use functional components to export them with: withMedia().
Now I need to use a class component but I'm not doing it right.
This is from "react-media-query-hoc" docs:
import { withMedia } from 'react-media-query-hoc';
const MyComponent = ({ media, ...props}) => (
if(media.tablet || media.mobile) {
..
return (
<div>
Mobile and Tablet View
</div>
)
}
return (
<div>
Other View
</div>
)
);
export const BaseMyComponent = MyComponent;
export default withMedia(MyComponent);
I need to transform this to a class Component, please some Help will be great :)
https://www.npmjs.com/package/react-media-query-hoc
It should be something like this:
import { withMedia } from 'react-media-query-hoc';
import React from 'react';
class MyComponent extends React.Component {
render(){
if(this.props.media.tablet || this.props.media.mobile) {
...
return (
<div>
Mobile and Tablet View
</div>
)
}
return (
<div>
Other View
</div>
)
}
}
export const BaseMyComponent = MyComponent;
export default withMedia(MyComponent);

Categories

Resources