I am trying to add a drop down calendar but I get warning from the code below and
there is not drop down calendar when cursor was placed over the input box.
Warning from the developer tool, console panel:
VM2542 react-dom.development.js:86 Warning: componentWillReceiveProps has been renamed, and >is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.
Move data fetching code or side effects to componentDidUpdate.
If you're updating state whenever props change, refactor your code to use memoization
techniques or move it to static getDerivedStateFromProps. Learn more at: >https://reactjs.org/link/derived-state
Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all >deprecated lifecycles to their new names, you can run npx react-codemod rename-unsafe->lifecycles in your project source folder.
Please update the following components: DateInput
ExpenseForm.js
import React from "react";
import moment from "moment";
import 'react-dates/lib/css/_datepicker.css'
import 'react-dates/initialize';
import { SingleDatePicker } from "react-dates";
export default class ExpenseForm extends React.Component {
state = {
createdAt: moment(),
calendarFocused: false
}
onDateChange = (createAt) => {
this.setState(()=>({createAt}))
}
onFocusChange = ({focused}) => {
this.setState(()=>{calendarFocused: focused})
}
render(){
return (
<div>
<SingleDatePicker
date={this.state.createdAt} // momentPropTypes.momentObj or null
onDateChange={this.onDateChange} // PropTypes.func.isRequired
focused={this.state.calendarFocused} // PropTypes.bool
onFocusChange={this.onFocusChange} // PropTypes.func.isRequired
numberOfMonths={1}
isOutsideRange={()=>false}
/>
<button>Submit</button>
</div>
)
}
}
I am also getting a hint warning on VSCode on the line:
import 'react-dates/initialize';
Could not find a declaration file for module 'react-dates/initialize'. 'c:/Users/PEI WAI LEE/Programming/ReactCourse/my-provider/node_modules/react-dates/initialize.js' implicitly has an 'any' type.
If the 'react-dates' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-dates'ts(7016)
I change this line
onFocusChange = ({focused}) => {
this.setState(()=>{calendarFocused: focused})
}
to
onFocusChange = ({focused}) => {
this.setState(()=>({calendarFocused: focused}))
}
without the brackets the statement won't return calendarFocused
The calendar is now showing when I hover the cursor to the input box
can someone advise the warning and the hit warning on VSCode?
Related
I am following a guide to upgrade to React 18. After completing the upgrade I am seeing errors on certain pages in my app.
ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18.
I am not using the unstable_renderSubtreeIntoContainer() function anywhere in my app, but when I look closer at what is causing these errors it seems to be caused my Bootstrap components.
Is there anyway to update this to remove the errors?
I ran into the same problem with react-bootstrap#v0.33.1 specifically when using OverlayTrigger component after upgrading to React 18. The warning message suggests to migrate to using portals. So I implemented a CustomOverlayTrigger component that leverages portals and referred to React's portal documentation to do so. Note that this solution is for Bootstrap 3 usage of OverlayTrigger (react-bootstrap v0.33.1). It seems later versions of react-bootstrap got rid of using ReactDOM.unstable_renderSubtreeIntoContainer. If you are not in a position to migrate to later versions (like I am), this solution will help for this use case. I have not check thoroughly if other components use the deprecated method, but the approach might be the same.
First of all, I copied the original source of the OverlayTrigger component code located here. You will need to clean up the imports and include into your code the utils function createChainedFunction located here.
I then created a portal wrapper based off React's documentation that looks like this:
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
const tooltipRoot = document.getElementById('tooltip-root');
class PortalWrapper extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
tooltipRoot.appendChild(this.el);
}
componentWillUnmount() {
tooltipRoot.removeChild(this.el);
}
render() {
// eslint-disable-next-line react/destructuring-assignment
return ReactDOM.createPortal(this.props.children, this.el);
}
}
PortalWrapper.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
};
export default PortalWrapper;
At the top, you can see the line const tooltipRoot = document.getElementById('tooltip-root');, I simply added in my index.html a div next to the react app's root div that will server as the anchor for my portal.
Then, back in the CustomOverlayTrigger component copied from react-bootstrap, I edited it in the follwing manner:
Remove all references to this._overlay and this._mountNode because the PortalWrapper now manages the mounting/unmounting. So I deleted componentDidMount(), componentDidUpdate(), componentWillUnmount() and renderOverlay()
I modified makeOverlay so that its result is wrapped by PortalWrapper so it became the following:
makeOverlay(overlay, props) {
return (
<PortalWrapper>
<Overlay
{...props}
show={this.state.show}
onHide={this.handleHide}
target={this}
>
{overlay}
</Overlay>
</PortalWrapper>
);
}
Finally, I changed the render method's return statement to become:
return (<>
{cloneElement(child, triggerProps)}
{this.makeOverlay(overlay, props)}
</>);
After this, I simply had to replace all my invocations to OverlayTrigger with CustomOverlayTrigger and I had the same result without the warning message.
I'm trying to use the Link component in #fluentui/react, but I get an error about invalid hook calls. I tried using Link in office-ui-fabric-react, but got same hook error.
Background:
Component A calls the code with the Link component.
Component A is in a different folder than Link component.
Error:
"react-dom.development.js:3198 Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app"
Link code:
import * as React from "react";
import { Link } from "#fluentui/react";
//import { Link } from "office-ui-fabric-react";
export interface ITestProps {
what: string;
click: () => void;
}
export default class TestComponent extends React.PureComponent<ITestProps, {}> {
constructor(props: ITestProps) {
super(props);
}
render() {
return (
<div>
Test {this.props.what}
<button onClick={this.props.click}>Click</button>
<Link onClick={this.props.click}>Click link</Link> <-- this is what is causing hook problems
</div>
);
}
}
Then I tried using a functional component rather than extending from React.PureComponent, but same hook error:
export default function TestComponent(props: ITestProps) {
return (
<div>
Test2 {props.what}
<button onClick={props.click}>Click</button>
<Link onClick={props.click}>Click link</Link> <-- also produces hook error
</div>
);
}
The only way that I solved this problem is my Link code inside the same folder as the Component that uses the Link code.
I want to be able to put my Link code in a separate folder, not in the same folder as Component A.
I also made sure that the react and react-dom version of both folders are the same, but I still got hook errors.
Please any suggestions?
I'm trying to use this library https://github.com/country-regions/react-country-region-selector for my react native application.
The example code is as follows:
import React from "react";
import { View, Text } from 'react-native';
// note that you can also export the source data via CountryRegionData. It's in a deliberately concise format to
// keep file size down
import {
CountryDropdown,
RegionDropdown,
CountryRegionData
} from "react-country-region-selector";
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { country: "", region: "" };
}
selectCountry(val) {
this.setState({ country: val });
}
selectRegion(val) {
this.setState({ region: val });
}
render() {
const { country, region } = this.state;
return (
<View>
<CountryDropdown
value={country}
onChange={val => this.selectCountry(val)}
/>
<RegionDropdown
country={country}
value={region}
onChange={val => this.selectRegion(val)}
/>
</View>
);
}
}
export default Example;
I changed the divs in the render method into View, which has left me with the current error: Invariant Violation: View config not found for name option.
I'm not sure if this is because the library is intended for React as opposed to React-Native or if there is something else going on that I'm unaware of.
This won't work because this library renders HTML, which is not available in react-native. You can confirm this by going to node_modules/react-country-region-selector/src to see the source code.
However, the Picker component in react-native has a very similar API, so you could easily remake this to be compatible. Note that you should not edit files in your node_modules as they will be corrected any time you run yarn / npm. Instead, you should create your own local version of this module.
It's really just a matter of replacing select with Picker and option with Picker.Item and changing the onChange handlers to work with the Picker instead of expecting a DOM event.
You can learn more about the Picker API here
I am trying to use proptypes for in my react-redux app, but it is not working, or I am doing something wrong. this is end of code example:
LoginPage.propTypes = {
login_form: PropTypes.string
};
function mapStateToProps(state) {
return { loginPage: state.loginPage }
}
export default connect(mapStateToProps)(LoginPage);
login_form is boolean, and I intentionaly wrote PropType.string to see if it was working but it didn't give me any errors, this is probably because of redux connect,but I couldn't search anything about that. please anyone tell me what I am doing wrong :/ thanks.
From the docs:
When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. For performance reasons, propTypes is only checked in development mode.
If you're running the project that is not in development mode, then you cannot see the warning.
See update below: Also, PropTypes doesn't throw an error but show warning. Be sure to check warning in the console. You might have selected to show error only.
And also, be sure to import the PropTypes from 'prop-types' to work with PropTypes:
import PropTypes from 'prop-types'
If the above thing is assured and you still don't see the warning in the console, then there's one probability you pass boolean value in string:
<LoginPage login_form="true" />
Or,
<LoginPage login_form={'true'} />
Be sure to pass boolean value like this:
<LoginPage login_form={true} />
Note: if you want to pass the true value, you may just pass the props like this:
<LoginPage login_form />
Now, having login_form: PropTypes.string will show you warning.
Update:
Though react doc says it will throw warning, I just verified that it actually throws an error without application hold. But the message is starting with Warning:. Thus, be sure to check error in the console not warning.
Or, you may be sure to check default.
React will automatically check the propTypes you set on the component and show [warning] in the console.
But if you are using PropTypes without React then you can manually call PropTypes.checkPropTypes so in your case.
const myPropTypes = {
login_form: PropTypes.string,
// ... define your prop validations
};
const props = {
login_form: true, // not valid
};
PropTypes.checkPropTypes(myPropTypes, props, 'prop', 'LoginPage');
import React ,{ Component }from 'react';
import PropTypes from 'prop-types'
class Person extends Component {
render(){
console.log('person.js-rendering- child components');
return (
<div classes="person">
<p onClick={this.props.personClick}>I am {this.props.name} and I am {this.props.age} years old</p>
<p>{this.props.children}</p>
<input type="text" onChange={ this.props.personChange } id='inputName' value={ this.props.name } />
</div>
)
}
}
Person.propTypes={
personClick:PropTypes.func,
children:PropTypes.func,
personChange:PropTypes.func,
name:PropTypes.string,
age:PropTypes.number
}
export default Person;
I have included material-ui (and react-tap-event-plugin) in my project and added 3 buttons to one of my components:
<RaisedButton onClick={this.props.onSave} label="Save" style={styles.button}/>
<RaisedButton label='Publish' onClick={this.props.onPublish} style={styles.button}/>
<RaisedButton label='Cancel' onClick={this.onCancel.bind(this)} style={styles.buttonCancel}/>
when I click on any of these, they go very dark grey and when I click again, they go black (and stay like that). The whole applications goes bonkers, the react routing no longer works (I can see the URL changing in the address bar, but the view doesn't refresh). This all looks pretty bad for a button click :)
Any idea what I may be doing wrong? (I take care of the childContext as described in the docs, so the muiTheme is loaded).
I forgot to check the console... there are 3 exceptions whenever I press the button:
1)
vendor.js:12 Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
2)
ReactTransitionGroup.js:176 Uncaught TypeError: Cannot read property 'componentWillLeave' of undefined(…)
3)
vendor.js:12 Uncaught Error: removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded (details: https://facebook.github.io/react/warnings/refs-must-have-owner.html).(…)
In the component that uses FlatButton (or RaisedButton neither work) I have this:
1) Import:
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
2) in the class
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
3) and a static declaration:
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Feels like I'm doing all that's required.
This may be related to what I'm experiencing:
https://github.com/callemall/material-ui/issues/2818
So probably the issue is caused by material-ui distributing it's own version of React? What's the point in that? But... my version of material-ui doesn't have a node_modules folder, so no extra React either...
Source for a component importing and using FlatButton
import React from 'react'; // eslint-disable-line
import Input from '../../../components/common/textInput'; // eslint-disable-line
import BaseEditorComponent from '../base/EditorComponent';
import FlatButton from 'material-ui/FlatButton'; //eslint-disable-line
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default class EditorComponent extends BaseEditorComponent {
constructor() {
super();
this.state = {
textValue: 'Enter value'
};
}
getChildContext() {
return { muiTheme: getMuiTheme(baseTheme) };
}
_onChange(e) {
this.setState({
textValue: e.target.value
});
}
render() {
return (
<div>
<Input
value={this.state.textValue}
name="SimpleText"
label="Simple Text Value:"
onChange={this._onChange.bind(this)}
/>
<FlatButton label="Test"/>
</div>
);
}
}
EditorComponent.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};
Also, the BaseEditorComponent:
import React from 'react';
import widgetActions from '../../widgets/WidgetActions';
import widgetInstanceStore from '../../widgets/WidgetInstanceStore';
export default class EditorComponent extends React.Component {
constructor() {
super();
}
componentDidMount() {
this.setState(widgetInstanceStore.getWidgetInstanceState(this.props.widgetId) || {});
}
save() {
widgetActions.saveWidgetInstanceState(this.props.widgetId, this.state);
}
}
Have you tried to use onTouchTap instead of onClick?
If #1 doesn't help, please show more code - component with above code and it's parent component.
As per https://github.com/callemall/material-ui/issues/2818 the solution was to include react-addons-transition-group alongside react in the browserify bundle. So it's good to know that it's not only NPM where a 2nd copy of react can slip through, but also browserify or webpack.
Thanks https://stackoverflow.com/users/3706986/piotr-sołtysiak for helping with the issue today!