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>
);
}
}
Related
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
I am a newbie for react js. how to manage two Countdown timers first start and second is stop after 5-second interval second start and first stop.
it work for single Clock successful but add two clocks then first only start and not stop while second not start I don't know how do this ?.
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
isActive: true
};
}
componentDidMount() {
this.intervalId = setInterval(() => {
this.randomCallObject();
}, 5000);
}
randomCallObject() {
this.setState({
Active: !this.state.isActive
});
}
render() {
let clock= {
time: 150,
isActive:this.state.isActive
}
let clock2= {
time: 100,
isActive:!this.state.isActive
}
return (
<div className="container">
<Clcok ClockData={clock}/>
<Clcok ClockData={clock2}/>
</div>
);
}
}
import React, { Component } from "react";
const TOTAL_MINUTES = 60;
export default class ClockComponent extends Component {
constructor(props) {
super(props);
this.state = {
time: props.ClockData.time,
isActive: props.ClockData.isActive
};
}
componentDidMount() {
const { isActive } = this.state;
if (isActive === true) {
this.intervalId = setInterval(() => {
const { time } = this.state;
if (time > 0) {
this.setState({
time: time - 1
});
}
}, 1000);
}
}
componentWillUnmount() {
clearInterval(this.intervalId);
}
render() {
const { time } = this.state;
let minutes ="" + Math.floor((time % (TOTAL_MINUTES * TOTAL_MINUTES))/ TOTAL_MINUTES);
let seconds = "" + Math.floor(time % TOTAL_MINUTES);
if (isNaN(minutes) || isNaN(seconds)) {
return null;
}
if (minutes.length === 1) {
minutes = `0${minutes}`;
}
if (seconds.length === 1) {
seconds = `0${seconds}`;
}
return (
<div className="row">
<div className="col-md-1">
<div>
{minutes}:{seconds}
</div>
</div>
</div>
);
}
}
when clock data comes from props so take simple objects when isActive flag is true then clock timer on when isActive false then timer stop
To learn how to handle setInterval with React, I suggest you read the following blog post by Dan Abramov:
Making setInterval Declarative with React Hooks
In it, he explains how to use setInterval using React Hooks and also how to do it using a class component. On the post, there is also a link to a CodeSandbox example where you can see it in action.
What I did was create another CodeSandbox where you can see how you could apply this example to run multiple timers:
https://codesandbox.io/embed/timers-l6me1
I've used React Hooks in the example because they don't require a lot of code.
I hope it helps.
edit #1
Here is an example of a Counter component taken directly from the mentioned article, and adapted to fit the latter example.
class Counter extends React.Component {
state = {
count: 0,
delay: 1000,
isRunning: true
};
constructor(props) {
super(props);
this.state = { ...this.state, ...props };
}
componentDidMount() {
this.interval = setInterval(this.tick, this.state.delay);
}
componentDidUpdate(prevProps, prevState) {
if (prevState.delay !== this.state.delay) {
this.startInterval();
}
}
componentWillUnmount() {
clearInterval(this.interval);
}
startInterval = () => {
clearInterval(this.interval);
this.interval = setInterval(this.tick, this.state.delay);
console.log(this.interval);
};
tick = () => {
this.setState({
count: this.state.count + 1
});
};
handleDelayChange = e => {
this.setState({ delay: Number(e.target.value) });
};
toggleCounter = () => {
console.log(this.state.isRunning);
if (this.state.isRunning) {
clearInterval(this.interval);
} else {
this.startInterval(this.state.delay);
}
this.setState({
count: 0,
isRunning: !this.state.isRunning
});
};
render() {
const {
state: { isRunning, delay, count },
toggleCounter,
handleDelayChange
} = this;
return (
<>
<h1>{count}</h1>
<input value={delay} onChange={handleDelayChange} />
<button onClick={toggleCounter}>{isRunning ? "stop" : "start"}</button>
</>
);
}
}
Please HELP!
I fill data in componentdidupdate
componentDidUpdate(prevProps) {
if(isEmpty(this.props.tofiConstants)) return;
const { doUsers, dpUsers } = this.props.tofiConstants;
if (prevProps.cubeUsers !== this.props.cubeUsers) {
this.setState({
data: somefunc(doing here something)
});
}
console.log(this.state.data);
}
and then i want use the state in render
render() {
return (
<div className="profileScreen">{this.state.fullname}</div>
);
}
constructor is here
constructor(props) {
super (props);
this.state = {
data: []
};
}
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>
);
}
}
so i have this in my code like this:
class TimersDashboard extends React.Component{
constructor() {
super(props);
this.state = {
timers: [
{id: uuid.v4(), text:'I am the first id' },
{ id:uuid.v4(), text:'I am the second text' }
]
};
}
clickEdit(id) {
this.openForm(id);
}
openForm(id) {
this.setState({
timers: this.state.timers.map((timer) => {
if(timer.id === id) {
return Object.assign({}, timer, { editFormOpen: true });
} else {
return timer;
}
})
});
}
handleCloseForm(id) {
this.closeForm(id);
}
closeForm(id) {
this.setState({
timers: this.state.timers.map((timer) => {
if(timer.id === id) {
return Object.assign({}, timer, { editFormOpen: false });
} else {
return timer;
}
})
});
}
}
render() {
return (
<Timer id={this.state.data[0].id} onEdit={this.clickEdit.bind(this)} onDelete = {this.handleCloseForm.bind(this)}/> // as if wroking on the first id
);
}
}
}
However, below, I passed the methods as props, the other component I tried to invoke these the same way, you can see their code is slightly similar in way.
class Timer extends React.Component {
constructor(props) {
super(props);
this.handleEditClick = this.handleEditClick.bind(this);
this.handleTrashClic = handleTrashClic.bind(this);
}
handleEditClick() {
this.props.onDelete(this.props.id);
}
handleTrashClick() {
this.props.onEdit(this.props.id);
}
render() {
return(
// ... onClick = {()=>this.handleEditClick(this.props.id)} ..
// ... onClick = {()=>this.handleTrashClick(this.props.id)} ..
);
}
}
}
I code them same way on other component, the delete method works on other component but I don't know why the Edit method does not and I can't make it work, I tried to pass the parentObj context, added .bind(this), But I cannot make it work. My error is "Warning: undefined(...): Cannot update during an existing state transition...". How do I make it work?
Created the same example in jsfiddle, its working. Try this:
Parent Component:
class TimersDashboard extends React.Component{
constructor(props) {
super(props);
this.state = {
timers: [
{id: 1, text:'I am the first text' },
{id: 2, text:'I am the second text' }
]
};
}
edit(id){
let timers = this.state.timers.map((timer) => {
if(timer.id === id) {
return Object.assign({}, timer, { editFormOpen: true });
} else {
return timer;
}
})
this.setState({timers});
}
remove(id){
let timers = this.state.timers.map((timer) => {
if(timer.id === id) {
return Object.assign({}, timer, { editFormOpen: false });
} else {
return timer;
}
})
this.setState({timers});
}
render() {
return (
<div>
<Timer id={1} edit={this.edit.bind(this)} remove={this.remove.bind(this)}/>
</div>
);
}
}
Child Component:
class Timer extends React.Component{
constructor(props) {
super(props);
this.state={};
}
edit(id){
this.props.edit(id);
}
remove(id){
this.props.remove(id);
}
render(){
return(
<div>
In Child Component:
<br/>
Id: {this.props.id}
<p onClick={this.edit.bind(this,this.props.id)}>Edit</p>
<p onClick={this.remove.bind(this,this.props.id)}>Remove</p>
*click on edit and remove to change the state
</div>
)
}
}
Check jsfiddle for working example: https://jsfiddle.net/wqkfqusk/