How to generate random numbers where user refresh the page in react - reactjs

Hi I am creating a chat bot using react.My code is:
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
random : '',
}
}
componentDidMount(){
addResponseMessage('Welcome to React Bot! Type start');
return this.setState({random : Math.floor(Math.random()*10000)});
}
handleNewUserMessage = (newMessage) => {
fetch('http://localhost:5005/webhooks/rest/webhook', {
method: 'POST',
headers : new Headers(),
body:JSON.stringify({"sender":this.state.random, "message": newMessage}),
}).then((res) => res.json())
.then((data) => {
var first = data[0];
var mm= first.text;
var i;
console.log(mm)
toggleMsgLoader();
setTimeout(() => {
toggleMsgLoader();
if (data.length < 1) {
addResponseMessage("I could not get....");
}
else{
addResponceMessage(mm)
}
}
}
handleQuickButtonClicked = (e) => {
addUserMessage(e);
this.handleNewUserMessage(e);
setQuickButtons([]);
}
render() {
return (
<Widget
title="Rasa Sample Bot"
subtitle="Asistente virtual"
senderPlaceHolder="Type here ..."
handleNewUserMessage={this.handleNewUserMessage}
handleQuickButtonClicked={this.handleQuickButtonClicked}
badge={1}
/>
);
}
}
When user give to messages to my bot.It will call handleNewUsermMessage() and execute and give responses to user. body:JSON.stringify({"sender":this.state.random, "message": newMessage}), this code for when user refreshing the page that sender id will be change. But here every message it will create a random Id. I don't want every message. Whenever user refresh the page then only i want create random id.
How to solve this. Please help. Thanks in advance

Define in your state
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
random: Math.floor(Math.random()*100),
}
}
handleClick = () => {
this.setState({random: this.min + (Math.random() * (this.max - this.min))});
};
render() {
return (
<div>
<button onClick={this.handleClick}>Click me</button>
{this.state.random}
</div>
);
}
}

try this write in componentDidMount.
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
random : '',
}
}
componentDidMount() {
this.setState({random : Math.floor(Math.random()*100)});
}
handleClick = () => {
this.setState({random: this.min + (Math.random() * (this.max - this.min))});
};
render() {
return (
<div>
<button onClick={this.handleClick}>Click me</button>
{this.state.random}
</div>
);
}
}

In react when you refresh the browser the components remounts. So to generate random number on refresh you should call the random number generating function in componentDidMount() lifecycle method. The below code will work.
class Button extends React.Component {
constructor(props) {
super(props);
this.state = {
random: null,
}
}
min = 1;
max = 100;
generateRandom =()=>{
this.setState({random: this.min + (Math.random() * (this.max
this.min))
}});
componentDidMount(){
this.generateRandom();
}
handleClick = () => {
this.generateRandom();
};
render() {
return (
<div>
<button onClick={this.handleClick}>Click me</button>
{this.state.random}
</div>
);
}
}

this.state = {
random: Math.floor(Math.random()*100)
}
Just Update the above line in the constructor and it will all work just fine

Related

delete array item cause error perform a React state update on an unmounted component

I have google for this problem.
The solution is put is_Mounted in componentWillMount and unmount, but this will let deletion not happened.
I would appreciate it greatly if you could let me know how to deal with this problem which I deal with for about a week.
My pseudocode...
IRPage
class IRPage extends Component {
state = {
companyList: [],
contractListOfList: [],
};
addCompanyArr = (newCompany) => {
this.setState(
state => {
const list = state.companyList.push(newCompany);
return {
list,
};
}
)
};
addContractArr = (newContractList) => {
this.setState(
state => {
const list = state.contractListOfList.push(newContractList);
return {
list,
};
}
);
}
render() {
return (
// pass array method.....to IRContent
)
}
}
IRContent
class IRContent extends React.Component {
constructor(props) {
super(props);
}
addCompany = () => {
const companyNode = <IRCompany setContractArr={this.props.setContractArr} contractList={newContractList} companyList={this.props.companyList} setCompanyArr={this.props.setCompanyArr} addContractArr={this.props.addContractArr}/>;
this.props.addCompanyArr(companyNode);
var newContractList = [];
this.props.addContractArr(newContractList);
}
render() {
return(
<div>
{
this.props.companyList.map((element, index) => {
return <div key={"myCompanyKey_"+index+"_"+this.props.companyList.length} id={index}>{element}</div>;
})
}
<button color="primary" onClick = {this.addCompany}>
add company
</button>
</div>
);
}
}
IRCompany
class IRCompany extends React.Component {
constructor(props) {
super(props);
}
state = {
contractList: this.props.contractList,
};
deleteCompany = event => {
event.preventDefault();
// var targetID = ; I'm sure this is correct in original code
this.props.companyList.splice(targetID, 1);
this.props.contractListOfList.splice(targetID, 1);
this.props.setCompanyArr();
};
addContract = event => {
event.preventDefault();
var newContract = <IRContract contractList={this.state.contractList} setContractList={this.setContractList} setCompanyArr={this.props.setCompanyArr} contractListOfList={this.props.contractListOfList} setContractArr={this.props.setContractArr}/>;
this.props.contractList.push(newContract);
this.setContractList();
};
setContractList = () => {
this.setState(
state => {
const list = state.contractList;
return {
list,
};
}
)
}
render() {
return(
<div>
{
this.state.contractList.map((element, index) => {
return <tbody key={"myContractKey" + index + "_" +this.state.contractList.length} id={index}>{element}</tbody>;
})
}
</div>
);
}
}
IRContract
class IRContract extends React.Component {
constructor(props) {
super(props);
}
deleteMainContract = event => {
event.preventDefault();
this.props.contractList.splice(contractNum, 1);
this.props.setContractList();
};
render() {
return(
<React.Fragment>
<button name="deleteMainContract" type="button" onClick={this.deleteMainContract} style={{borderRadius: "6px", fontSize: "16px"}}>delete</button>
</React.Fragment>
);
}
}
If I click add company, add contract, and delete contract, it will work correctly.
However, if I click add company, add contract, add another company, and delete contract, it will fail.
Error message is "Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.", but I never write something like componentWillUnmount.

How to reload "url" every second using React

I want to reload URL every 5 seconds. Below is my code. What do I do wrong? Please let me know is there anything important point which I missed.
class RandomImg extends Component {
constructor(props) {
super(props);
this.state = { image: "https://picsum.photos/100" };
}
componentDidMount() {
this.imgID = setInterval(() => {
this.tickImg();
}, 1000);
}
componentWillUnmount() {
clearInterval(this.imgID);
}
tickImg() {
this.setState({ image: "https://picsum.photos/100" });
}
render() {
return (
<div>
<h4>This is Random IMG:</h4>
<img src={this.state.image}></img>
</div>
);
}
}
Your image URL is not changing and thus the component is not being updated.
Try this
class RandomImg extends Component {
constructor(props) {
super(props);
this.state = { image: "https://picsum.photos/100" };
}
componentDidMount() {
this.imgID = setInterval(() => {
this.tickImg();
}, 1000);
}
componentWillUnmount() {
clearInterval(this.imgID);
}
tickImg() {
this.setState({ image: "https://picsum.photos/100?" + Math.random() });
}
render() {
return (
<div>
<h4>This is Random IMG:</h4>
<img src={this.state.image}></img>
</div>
);
}
}
You URL is not changing on the tick so the state remains the same. Try adding some random string into the URL
for e.g.
tickImg() {
this.setState({random: this.state.random++ } , () => {
this.setState({ image: "https://picsum.photos/100?r=" + this.state.random });
})
}
class RandomImg extends Component {
constructor(props) {
super(props);
this.state = { image: "https://picsum.photos/100" };
}
componentDidMount() {
this.imgID = setInterval(() => {
this.tickImg();
}, 5000);
}
componentWillUnmount() {
clearInterval(this.imgID);
}
tickImg() {
this.setState({
image: `https://picsum.photos/${Math.floor(Math.random()*100)}`
});
}
render() {
return (
<div>
<h4>This is Random IMG:</h4>
<img src={this.state.image}></img>
</div>
);
}
}

How to receive props only after state of parent has updated?

I'm trying to build a little weather widget, where the geolocation of the user is captured in one component and then passed onto a child component which fetches the weather data (based on the location) and then eventually renders an icon indicating the current weather conditions.
I'm passing the longitude and latitude state as props to my WeatherWidget. Unfortunately, the WeatherWidget also receives the initial state null. How I can I avoid that?
Thank you for your help!
class GetGeolocation extends Component{
constructor(){
super();
this.state = {
lngt: null,
latd: null
}
}
componentDidMount(){
this.getLocation()
}
getLocation = () => {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(position => {
this.setState({lngt: position.coords.longitude.toFixed(4)});
this.setState({latd:position.coords.latitude.toFixed(4)});
}
);
};
}
render(){
return (
<>
<WeatherWidget lngt = {this.state.lngt} latd = {this.state.latd} />
</>
)
}
class WeatherWidget extends Component{
constructor(props){
super(props);
this.state = {
weather:[]
}
}
componentWillReceiveProps(nextProps){
this.getWeather(nextProps)
}
getWeather = (location) => {
console.log(location)
// The console logs twice:
// First:
//{lngt: "-12.3456", latd: null}
//Then, the correct values:
//{lngt: "-12.3456", latd: "78,9999"}
}
Don't use componentWillReceiveProps, that will be deprecated in later versions of React.
But also, you can just setup conditional logic in your life-cycle methods to determine what code to execute.
componentWillReceiveProps(nextProps){
//condition says if both value are truthy then run code.
if(nextProps.lngt && nextProps.latd){
this.getWeather(nextProps)
}
}
You can also use componentDidUpdate()
componentDidUpdate(){
//condition says if both value are truthy then run code.
if(this.props.lngt && this.props.latd){
this.getWeather(this.props)
}
}
One option is to conditionally render in the parent component:
class GetGeolocation extends React.Component {
constructor(props) {
super(props);
this.state = {
lngt: null,
latd: null
};
}
componentDidMount() {
this.getLocation();
}
getLocation = () => {
// Simulate the network request
setTimeout(() => this.setState({ lngt: 100 }), 1000);
setTimeout(() => this.setState({ latd: 100 }), 1000);
};
render() {
const { lngt, latd } = this.state;
if (!lngt || !latd) return null;
return <WeatherWidget lngt={lngt} latd={latd} />;
}
}
class WeatherWidget extends React.Component {
constructor(props) {
super(props);
this.state = {
weather: []
};
}
componentDidMount() {
this.getWeather(this.props);
}
getWeather = location => {
console.log(location);
};
render() {
return null;
}
}

How to use onload in react?

To run the imagesrore function onload I have to call <img src="image_7.jpg" className="hide" alt="image_7.jpg"/> image but actually there is no use of this line and if I remove this onload doesn't work and function is not called. So how can I call the imagestore() onload in react.
class PicturesList extends React.Component {
constructor(props) {
super(props);
this.state = {
imagesarray: []
};
this.imagestore = this.imagestore.bind(this);
}
render() {
return (
<div>
<div onLoad= {() => this.imagestore()}>
<img src="image_7.jpg" className="hide" alt="image_7.jpg"/>
// To run the imagesrore function onload I have to call this image but actually there is no use of this line and if I remove this onload doesn't work and function is not called
</div>
<Gallery url={this.state.imagesarray}/>
</div>
);
}
imagestore()
{
const imgUrls=this.props.apikeys;
const objarr = Object.values(imgUrls);
this.setState({
imagesarray: objarr
});
}
}
what I want
class PicturesList extends React.Component {
constructor(props) {
super(props);
this.state = {
imagesarray: []
};
this.imagestore = this.imagestore.bind(this);
}
render() {
return (
<div>
<div onLoad= {() => this.imagestore()}>
// but when I did this imagestore() function not called
</div>
<Gallery url={this.state.imagesarray}/>
</div>
);
}
imagestore()
{
const imgUrls=this.props.apikeys;
const objarr = Object.values(imgUrls);
this.setState({
imagesarray: objarr
});
}
}
Instead of rendering the image which you dont want, you could simply load it in componentDidMount like
class PicturesList extends React.Component {
constructor(props) {
super(props);
this.state = {
imagesarray: []
};
this.imagestore = this.imagestore.bind(this);
}
componentDidMount() {
const img = new Image();
img.onload =() => {
// image has been loaded
this.imagestore()
};
img.src = 'image_7.jpg';
}
render() {
return (
<div>
</div>
<Gallery url={this.state.imagesarray}/>
</div>
);
}
imagestore() {
const imgUrls=this.props.apikeys;
const objarr = Object.values(imgUrls);
this.setState({
imagesarray: objarr
});
}
}
The above solution is just to call imageStore once an image is loaded. However if what you intend is to call imageStore when the component has fully loaded,just trigger this.imageStore() in componentDidMount
class PicturesList extends React.Component {
constructor(props) {
super(props);
this.state = {
imagesarray: []
};
this.imagestore = this.imagestore.bind(this);
}
componentDidMount() {
this.imagestore()
}
render() {
return (
<div>
</div>
<Gallery url={this.state.imagesarray}/>
</div>
);
}
imagestore() {
const imgUrls=this.props.apikeys;
const objarr = Object.values(imgUrls);
this.setState({
imagesarray: objarr
});
}
}
Use useEffect() in React. You would use it like this:
useEffect(()=>{
**INSERT CODE YOU WANT RUN ON LOAD HERE **
}, [])
Remember to import useEffect as well with
import React, { useEffect } from 'react'
Your onLoad function should be used at the <img> tag, not the <div/>.

How to pass function as props in React?

I have functional component GetWeather which I want to pass result of GetLocation function as props based on which GetWetaher will do something i.e. another get request (in the example below it only renders its props). I think it has to happen inside ComponentDidMount, not sure how to do it
function GetLocation() {
axios.get('http://ipinfo.io')
.then((res) => {
return res.data.loc;
})
}
function GetWeather(props) {
//more code here, including another get request, based on props
return <h1>Location: {props.location}</h1>;
}
class LocalWeather extends Component {
componentDidMount() {
//???
}
render() {
return (
<div >
<GetWeather location={GetLocation}/> //???
</div>
);
}
}
Update: So based on suggestion from Damian below is working for me
function GetWeather(props) {
return <h3>Location: {props.location}</h3>;
}
class LocalWeather extends Component {
constructor(props) {
super(props);
this.state = {
location: []
};
}
getLocation() {
axios.get('http://ipinfo.io')
.then((res) => {
this.setState({location:res.data.loc});
})
}
componentDidMount() {
this.getLocation();
}
render() {
return (
<div >
<GetWeather location={this.state.location}/>
</div>
);
}
}
You can do it alternatively also
constructor() {
super();
this.state = {
Location:[]
}
}
function GetLocation() {
axios.get('http://ipinfo.io').then((res) => {
this.setState ({
Location:res.data.loc;
});
});
}
function GetWeather(props) {
return <h1>Location: {this.props.location}</h1>;
}
class LocalWeather extends Component {
componentDidMount() {
//code
}
render() {
return (
<div >
<GetWeather location={this.GetLocation.bind(this)}/>
</div>
);
}
}

Resources