Can you help me in changing this React stateless functional component to React class based component including the withRouter and history object as given?
const Menu = withRouter(({history}) => (
<AppBar>
</AppBar>
))
export default Menu
class Menu extends React.Component {
render() {
// you can use this.props.history anywhere in the class
const { history } = this.props;
return <AppBar>...</AppBar>
}
}
export default withRouter(Menu);
First, create your class component and then, create a constructor for the class. You can then define the states required inside the constructor, something like this-
export default class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
SomeVar: xyz,
AnotherVar: undefined
}
}
render() {
return withRouter(({history}) => (
<AppBar> </AppBar>
));
}
}
Related
2 components :- ClickCounter, mouseHoverCounter !
1 HOC component to do the counting work.
earlier I was counting the click and mouse hover by writing separate counter method in each component(cliccounter,mousehovecounter),
but
now, I'm trying to pass the component into hoc counter & get the new component with only one change , where I'm passing a props to originalComponent and returning it to see the behavior but its now working...
import React, { Component } from 'react'
import updatedComponent from './hocCounter'
class ClickCounter extends Component {
constructor(props) {
super(props)
this.state = {
counter:0
}
}
ClickCounterHandler = () =>{
this.setState((prevState)=>{
return {counter:prevState.counter+1}
})
}
render() {
const count=this.state.counter
return (
<div>
<button onClick={this.ClickCounterHandler}>{this.props.name} Clicked {count} Times</button>
</div>
)
}
}
export default updatedComponent(ClickCounter)
import React, { Component } from 'react'
import updatedComponent from './hocCounter'
class HoverMouseCounter extends Component {
constructor(props) {
super(props)
this.state = {
counter:0
}
}
MouseOverCounter(){
this.setState((prevState)=>{
return {counter:prevState.counter+1}
})
}
render() {
const count=this.state.counter
return (
<div>
<h1 onMouseOver={this.MouseOverCounter.bind(this)}>{this.props.name} Hovered For {count} Time(s)</h1>
</div>
)
}
}
export default updatedComponent(HoverMouseCounter)
import React from 'react'
const updatedComponent = originalComponent => {
class newComponent extends React.Component {
render(){
return <originalComponent name='Harsh'/>
}
}
return newComponent
}
export default updatedComponent
In App.js, I'm returning
<ClickCounter></ClickCounter>
<HoverMouseCounter></HoverMouseCounter>
this only !
Check the error in the console,
index.js:1 Warning: <originalComponent /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements. at originalComponent
This means You are using the small letter in originalComponent
React components are expected to start with a capital letter
Try this in you HOC component
import React from 'react'
const updatedComponent = OriginalComponent => {
class NewComponent extends React.Component {
render(){
return <OriginalComponent name='Harsh'/>
}
}
return NewComponent
}
export default updatedComponent
How to send props to a component on the basis of system wide theme?
I know how to style my components with media query for dark and light themes with #media prefers-color-scheme , but I am working with react-json-vew library and component, it takes a theme prop, which I need to change when the system wide dark mode is toggled.
Its a custom component so I would not like to style it on my own, that would also increase the code's length.
Snippet :
import ReactJson from "react-json-view";
import React from "react";
class JsonDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false,
copied: false
};
}
render(){
return <ReactJson src={json} theme={"apathy:inverted"} /> // here I need to apply theme on the basis of dark or light mode
}
}
Why don't you use React Context API?
import React from 'react';
const ThemeContext = React.createContext();
export default class App extends React.Component {
render() {
return (
<ThemeContext.Provider value={'apathy:inverted'}>
<JsonDialog/>
{/* Other Components */}
</ThemeContext.Provider>
)
}
}
class JsonDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false,
copied: false
};
}
render() {
return(
<ThemeContext.Consumer>
{theme=> <ReactJson src={json} theme={theme} />}
</ThemeContext.Consumer>
)
}
}
So the easiest way is to receive a prop to your component that will describe if its in dark mode or light mode. I'll do the following example:
import ReactJson from "react-json-view";
import React from "react";
class JsonDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false,
copied: false
};
}
render(){
const themeName = this.props.dark ? 'apathy':'apahty:inverted'
return <ReactJson src={json} theme={themeName} /> // here I need to apply theme on the basis of dark or light mode
}
}
Another way is to use redux or some kind of state management for your app, but if its a simple app, the above should work.
This should do the trick
<ReactJson src={json} theme={this.props.dark ? "darkThemeName" : "lightThemeName"} />
How can I get intl.formatMessage from parent component? I wrapped parent component with injectIntl and want send intl.formatMessage to child component. Can someone help me with that? Thank you!
Parent component
import Car from "./test3";
import { injectIntl } from "react-intl";
class Intl extends React.Component {
render() {
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand="Ford" />
</div>
);
}
}
export default injectIntl(Intl);
Child component
import { FormattedMessage} from "react-intl";
class Car extends React.Component {
yearsTranslation = () =>
this.props.intl.formatMessage({ id: "search.filter.maturity.years" });
render() {
return <h2>Hello {this.yearsTranslation()}!</h2>;
}
}
export default Car;
Just pass the prop down, like so :
class Intl extends React.Component {
render() {
return (
<div>
<h1>Who lives in my garage?</h1>
<Car brand="Ford" intl={this.props.intl}/>
</div>
);
}
}
export default injectIntl(Intl);
I thinks intl is available in the context. Please check the documentation.
I have a React component that uses default props:
class MyComponent extends Component {
constructor(props) {
console.log('props', props);
super(props);
// rest of code here
}
MyComponent .defaultProps = {
__TYPE: 'MyDateRange',
};
When I use the component, without passing any props, the console log of props shows the default props, like it should.
Now, when I want to pass an additional prop (a function in this case), like this:
<MyComponent onEnterKey={() => console.log('snuh')}/>
The console log of props only shows the onEnterKey function.
What do I have to do to allow MyComponent to use the default props and accept a function? I've tried adding another argument to the constructor of MyComponent, but that doesn't work.
I tried and this is working :
import React from "react";
import { render } from "react-dom";
class MyComponent extends React.Component {
constructor(props) {
console.log("props", props);
super(props);
}
render() {
return null;
}
}
MyComponent.defaultProps = {
__TYPE: "MyDateRange"
};
render(
<MyComponent onEnterKey={() => console.log("snuh")} />,
document.getElementById("app")
);
You can see it here : https://codesandbox.io/s/wkw0k0j5o8
You can put the defaultProp on the class outside of the constructor like this:
class MyComponent extends Component {
constructor(props) {
console.log("props", props);
super(props);
}
render() {
return <div> test </div>;
}
}
MyComponent.defaultProps = {
__TYPE: "MyDateRange"
};
Alternatively, you can have defaultProps be a static property on the class:
class MyComponent extends Component {
static defaultProps = {
__TYPE: "MyDateRange"
};
constructor(props) {
console.log("props", props);
super(props);
}
render() {
return <div> test </div>;
}
}
I`m creating a react dynamic dialog where you can add functionality to the Dialog.
One way of doing this was with Composition, but I did not manage to do this via composition.
I`m not very experienced on React, so this was my first approach
I got my Modal component, and the modal has
export default class KneatModal extends React.Component {
constructor() {
super();
this.state = {
open: false
}
this.components = [];
I would add components like this
import CommentField from '../../../Modal/ModalContents/CommentField.jsx'
export default class DoApprove extends React.Component {
constructor() {
super();
}
componentDidMount() {
this._buildDialog();
}
_buildDialog() {
console.log("Building the Dialog");
this.modal.components.push(CommentField);
}
In that modal renderer, i have
<ModalContent components={ this.components } />
Then i the final renderer in ModalContent i try to render all attached components
render() {
var list = this.props.components.map((Component, key) => <Component/> );
return (
<div className='modal-contents'>
{list}
</div>
)
}
But the render method does not seems to work, i`ve tryed callin Component.render() instead of the component tag, but still could not make the sub-components render. =(
Would apreciate any help. Thanks
To be even more specific, this resumes on what im attempting
import PropTypes from 'prop-types';
import React from 'react';
import MyComponent1 from './MyComponent1.jsx'
import MyComponent2 from './MyComponent2.jsx'
export default class KneatModalContent extends React.Component {
constructor() {
super();
this.components = [MyComponent1, MyComponent2];
}
render() {
return (
<div className='modal-contents'>
{this.components.map(function (component, i) {
return <{ component } key= { i } />
})}
</div>
)
}
}