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);
Related
import React from 'react'
export default () => {
function clickHandler() {
console.log('Button clicked')
}
return (
<div>
<button onClick={clickHandler}>Click</button>
</div>
)
}
In the above code we see that a function has been passed to the onClick.In the same way to the onClick I need to pass a diffrent component which is present in the same src. This component consists of a .js and a .css file.Could you please help me out with it. Thanks in advance
If you don't mind using classes instead of functions, your other component should look like this:
import React from 'react'
class ShowThisAfterClick extends React.Component {
return (
<div>
<p>This is what you want to show</p>
</div>
)
}
export default ShowThisAfterClick
And now you should update the component you've shown:
import React from 'react'
import ShowThisAfterClick from './where/you/put/the/ShowThisAfterClick.js'
class Main extends React.Component {
constructor(props){
super(props)
this.state = { isButtonClicked: false }
this.clickHandler = this.clickhandler.bind(this)
}
clickHandler() {
this.setState({ isButtonClicked: true })
}
render() {
const { isButtonClicked } = this.state
return (
<div>
<button onClick={ this.clickHandler }>Click</button>
{ isButtonClicked ? <ShowThisAfterClick /> : ''}
</div>
)
}
}
export default Main
If you want to keep using functions, then I would kindly suggest to read the manual, it is more than well written.
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>
)
}
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>
);
}
};
Good day!
I am new to React and html2canvas. I am making an app which will take "screenshots" of my DOM using html2canvas then store it to an array of screenshots which will then be also rendered on the screen.
I am storing each <canvas> object received from the html2canvas promise to an array then pass it to my ScreenshotsContainer component which passes the array to the Screenshots component. The Screenshots component will then map the array of <canvas> objects to individual Screenshot components.
In App.js, I am calling the html2canvas function then pass the array to ScreenshotsContainer component
import React, { Component } from 'react';
import ScreenshotsContainer from './containers/ScreenshotsContainer/ScreenshotsContainer'
import html2canvas from 'html2canvas';
import './App.css';
class App extends Component {
state = {
canvasArray: []
}
getScreenshotHandler = () => {
console.log("[Canvas Array from state length:]" + this.state.canvasArray.length)
let canvasArray = this.state.canvasArray;
html2canvas(document.body).then((canvas) => {
canvasArray.push(canvas)
});
console.log("[Canvas Object value: ]" + canvasArray);
this.setState({ canvasArray: canvasArray })
}
render() {
return (
<React.Fragment>
<button onClick={this.getScreenshotHandler}>Get Screenshot</button>
<ScreenshotsContainer canvasArray={this.state.canvasArray} />
</React.Fragment>
);
}
}
export default App;
The ScreenshotsContainer component will pass the received array to the Screenshots component:
import React, { Component } from 'react';
import './ScreenshotsContainer.css'
import Screenshots from '../../components/Screenshots/Screenshots';
class ScreenshotsContainer extends Component {
render() {
return (
<div className="ScreenshotsContainer">
<Screenshots canvasArray={this.props.canvasArray} />
</div>
);
}
}
export default ScreenshotsContainer;
The Screenshots component will map the array and pass each canvas object to the Screenshot component:
import React, { Component } from 'react';
import Screenshot from './Screenshot/Screenshot';
class Screenshots extends Component {
render() {
const screenshots = this.props.canvasArray.map(canvas => {
return (
<Screenshot
key={Math.random}
canvasObj={canvas}
/>
)
})
return (
<React.Fragment>
{screenshots}
</React.Fragment>
);
}
}
export default Screenshots;
Here is the Screenshot component
import React from 'react';
import './Screenshot.css';
const screenshot = (props) => (
<div className="Screenshot" >
<canvas ref={props.canvasObj} style={{
width: '10%',
height: '10%'
}} />
</div>
);
export default screenshot;
What I actually get when pressing the button:
Actual screenshot of my result
I was wondering which part went wrong. Any help would be appreciated.
This particular library works in a specific way (looks like it's doing a lot of "magic" under the hood - you should look at the source code here more specifically the renderer folder inside src)
Saving the canvas to the state inside of an array (the correct react way of doing things) will be a problem as it saves it as a complex object with many methods etc... and we can not render objects... This lib was not written with React in mind...
The code sample below is a simple implementation in React...
Here is a live demo: https://codesandbox.io/s/9y24vwn1py
import React, { Component } from 'react';
import html2canvas from 'html2canvas';
class App extends Component {
constructor(props) {
super(props);
this.captureRef = React.createRef();
this.displayRef = React.createRef();
}
getScreenshotHandler = () => {
html2canvas(this.captureRef.current).then(canvas =>
this.displayRef.current.appendChild(canvas),
);
};
render() {
return (
<div>
<div ref={this.captureRef}>
<h2>This enitre div will be captured and added to the screen</h2>
</div>
<button onClick={this.getScreenshotHandler}>Get Screenshot!</button>
<section>
<h5>Your screenshots will be availbale below</h5>
<div ref={this.displayRef} />
</section>
</div>
);
}
}
export default App;
EDIT: based on the comment below here is yet another workaround:
class App extends Component {
constructor(props) {
super(props);
this.state = { canvasArray: [] };
this.captureRef = React.createRef();
}
getScreenshotHandler = () => {
html2canvas(this.captureRef.current).then(canvas =>
this.setState({
canvasArray: [canvas.toDataURL(), ...this.state.canvasArray],
}),
);
};
renderCanvas = () => {
return this.state.canvasArray.map((canvas, i) => {
return <img key={i} src={canvas} alt="screenshot" />;
});
};
render() {
return (
<div className="wrapper">
<div ref={this.captureRef}>
<p>This enitre div will be captured</p>
</div>
<button onClick={this.getScreenshotHandler}>Get Screenshot!</button>
<section>
<h5>Your screenshots will be availbale below:</h5>
{this.renderCanvas()}
</section>
</div>
);
}
}
Link to live demo: https://codesandbox.io/s/1r213057vq
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.