calling externally componentDidMount() in react - javascript

I have a requirement in which once page gets loaded my dropdownlist should be populated. for that I put that code in componentDidMount().
componentDidMount() {
axios.get(`http://localhost:8080/country_code`).then((res) => {
const countryData = res.data;
this.setState({ countryData });
alert(countryData);
});
}
I have one user input field in which person enter the value and save it into database. I want once user save that value into DB, my dropdown should get refresh and that value should be visible in the dropdown. How can I externally call componentDidMount()? is there any better way to handle the same?
As of now list is getting refreshed only when user resfresh the page.

You can't call externally componentDidMount() method !. so you need set
common function which is call in componentDidMount() and onChange dropdown value. see below code !
class App extends Component {
componentDidMount() {
this.handleCallApi();
}
handleCallApi = () => {
axios.get(`http://localhost:8080/country_code`).then((res) => {
const countryData = res.data;
this.setState({ countryData });
alert(countryData);
});
}
render() {
return (
<div>
<button onClick={this.handleCallApi}>Call Api</button>
</div>
);
}
}
export default App;

You can't call componentDidMount externally but you can extract the code in componentDidMount to a method and can call it in both componentDidMount and onSave.
alertDropDown = () => {
axios.get(`http://localhost:8080/country_code`).then((res) => {
const countryData = res.data;
this.setState({ countryData });
alert(countryData);
});
}
componentDidMount
componentDidMount() {
this.alertDropDown()
}
On DB save method
onSave = () => {
this.alertDropDown()
}

You can't call the componentDidMount(), as it's a lifecycle method and is called at initial render. You can expose a function and call that function from inside the componentDidMount() something like:
updateDropdownData = () => {
axios.get(`http://localhost:8080/country_code`).then((res) => {
const countryData = res.data;
this.setState({ countryData });
alert(countryData);
});
}
componentDidMount() {
this.updateDropdownData()
}
And you can call this.updateDropdownData() from anywhere you want. Just like:
onSomeUserAction = () => {
this.updateDropdownData()
}

Related

How to render an array of strings using map in ReactJs?

I basically want to put each string in the array in a separated div, I'm trying to do this but is not rendering anything
export default class Loja extends Component {
state = {
loja: {},
lojaInfo: {},
category: []
}
async componentDidMount() {
const { id } = this.props.match.params;
const response = await api.get(`/stores/${id}`);
const { category, ...lojaInfo } = response.data
this.setState({ loja: category, lojaInfo });
console.log(category)
}
render() {
const { category } = this.state;
return (
<p>{category.map(cat => <div>{cat}</div>)}</p>
);
}
}
The console.log(category) shows this:
The error is that you're updating 2 properties inside the componentDidMount, one is loja: category and the second property is lojaInfo, but in the render() method you're accessing this.state.category which still is an empty string.
What you want to do instead is, inside of your componentDidMount update your state like this:
this.setState({
category,
lojaInfo,
});
you've added your category into the loja object in the state.
something like this should work:
async componentDidMount() {
const { id } = this.props.match.params;
const response = await api.get(`/stores/${id}`);
const { category, ...lojaInfo } = response.data
this.setState({ category, lojaInfo });
}

Updating state of a class inside a function in React

I am trying to update the state of this class with the array of objects stored in the variable childData. However, when I use setState({childData: childData)}, and use it later on by calling this.state.childData, it is undefined, so it never updates the states with the information.
class Users extends React.Component {
state = {
childData: ""
}
retrieve = () => {
let childData;
var leadsRef = database.ref('users');
leadsRef.on('value', function(snapshot) {
childData = snapshot.val();
console.log(childData)
this.setState({
childData: childData
})
});
}
componentDidMount() {
this.retrieve()
}
render() {
return(
<div>
<h3>These are all the users in the app</h3>
{console.log(this.state.childData)}
</div>
)
}
}
export default Users
You have a couple issues going on. First, you do indeed need to set state within the callback function. However, as is, you'll hit an infinite loop. That's because you shouldn't be performing the async function in the render method. Instead, do it in the componentDidMount method so it only fires when the component mounts.
class Users extends React.Component {
state = {
childData: ""
}
retrieve = () => {
let childData;
var leadsRef = database.ref('users');
leadsRef.on('value', snapshot => {
childData = snapshot.val();
console.log(childData)
this.setState({
childData: childData
})
});
}
componentDidMount() {
this.retrieve()
}
render() {
return(
<div>
<h3>These are all the users in the app</h3>
{console.log(this.state.childData)}
</div>
)
}
}
export default Users
Try setting state inside the leadsRef.on callback function. For example:
leadsRef.on('value', snapshot => {
const childData = snapshot.val()
this.setState({childData})
})
Use this.setState in your callback. The code you are executing is non blocking so this.setState will be executed before you retrieved childDate.
Also make you callback function an arrow function.
Is this helpfull, I am not sure if it is correct.

how to delay the return in React until fetch is done

I am using React js and want to render data that I got it from API using Fetch .
the problem is I can't display the fetch results because the Return scope of React excute befor the fetch method done!!
Please any help of how I can solve this ???
this is a part of the function that do the Fetch :
initFourSquare = () => {
return fetch(FourSquareAPI)
.then(data => {
return data.json()
})
.catch((error) => {
console.log(error.message)
})
};
this is the render part of react where I called the function (initFourSquare)
render() {
var info = []
this.initFourSquare().then(response => {
info = response.response.venues
console.log(info) //the result is appear here
})
setTimeout(function(){ console.log(info[0].name) }, 1000);//the result is appear here
return (
<div>
<h1>{info}</h1> // it display nothing !!!
</div>
);
}
}
Any API/asynchronous call shouldn't be made in render function instead, you should do that in componentDidMount function if it is to be done once which seems to be your case and set the response in state which you can use in render. Make sure that you either initialise the state correctly or provide a conditional check for existence before using state variable
class App extends React.Component {
state = {
info: []
}
componentDidMount() {
var info = []
this.initFourSquare().then(response => {
info = response.response.venues
this.setState({info})
})
}
initFourSquare = () => {
return fetch(FourSquareAPI)
.then(data => {
return data.json()
})
.catch((error) => {
console.log(error.message)
})
};
render() {
const { info } = this.state;
return (
<div>
<h1>{info}</h1>
</div>
);
}
}

get value for api calling from other functions state REACTJS

So far I am calling an api in componentDidMount() and set it to select option.
also call another conditional api from user input.
But Problem is it is calling the api non stop.
**getRates(){
const base = this.handlePrint(this.state.value);
fetch(`https://exchangeratesapi.io/api/latest?base=${base}`)
.then(data => data.json())
.then(data =>{
this.setState({
rate: data.rates,
})
console.log(data.rates)
})
.catch(err => console.log(err))
}**
And my console screen shot:
console
I just need one time api call based on user input.
full code: https://codeshare.io/5MwXzq
I think there is a problem with the state but I am new in reactjs and could not understand how to solve that.
Anyone can help please.
This is happening not because of anything in componentDidMount()
Based on the code you shared on codeshare.io, you're calling getRates() function in your render() method. Also, you're setting the state using setState within the getRates method. This causes a re-render, calling render() again, and so you get the infinite loop of calls.
Remove the call to getRates() from your render method and it'll work.
EDIT:
Since there were small changes but strewn across your code to get it to work, I've modified your class and posting it here:
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
currencies: [],
value: "?",
base: "?",
input: "?",
rate: 0
};
this.getRates = this.getRates.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handlePrint = this.handlePrint.bind(this);
}
componentDidMount() {
fetch("https://exchangeratesapi.io/api/latest?symbols=USD,GBP,AUD,JPY")
.then(data => data.json())
.then(data => {
const currencies = [];
currencies.push(
data.base,
...Object.entries(data.rates).map(rates => rates[0])
);
this.setState({
currencies
});
})
.catch(err => console.log(err));
}
getRates() {
const base = this.handlePrint();
console.log(this.state); fetch(`https://exchangeratesapi.io/api/latest?base=${base}`)
.then(data => data.json())
.then(data => {
this.setState({
rate: data.rates
});
console.log(data.rates);
})
.catch(err => console.log(err));
}
//Dropdown
DropDown = function(list) {
return <option value={list}>{list}</option>;
};
handleChange(e) {
this.setState({ value: e.target.value });
}
handlePrint() {
console.log(this.state)
if (this.state.value) {
return this.state.value;
}
};
render() {
const { currencies } = this.state;
// const input = this.getRates();
return (
<div>
<span>SELECT your Base: </span>
<select autoFocus onChange={this.handleChange}>
<option inputcurrency={currencies} selected data-default>
SELECT BASE
</option>
{currencies.map(this.DropDown)}
</select>
<button onClick={this.getRates}>GET RAtes</button>
<p>selected base:{this.handlePrint()} </p>
</div>
);
}
}
The changes are:
1. Bound getRates() method in the constructor
2. Removed the call to getRates() in render start
3. Removed unnecessary items passed to handlePrint
4. Changed the button onClick to point to getRates

How to reload current page in ReactJS?

How to reload current page in ReactJS? in case of javascript we can write window.location.reload();
How to do the same in Reactjs? I'm able to add new data by UI. But without refreshing, I'm not able to see the list. I want it so that whenever I'm adding some data, it refreshes by itself.
onAddBucket() {
let self = this;
let getToken = localStorage.getItem('myToken');
var apiBaseUrl = "...";
let input = {
"name" : this.state.fields["bucket_name"]
}
axios.defaults.headers.common['Authorization'] = getToken;
axios.post(apiBaseUrl+'...',input)
.then(function (response) {
if(response.data.status == 200){
let result = self.state.buckets.concat(response.data.buckets)
}else{
alert(response.data.message);
}
})
.catch(function (error) {
console.log(error);
});
}
use this might help
window.location.reload();
You can use window.location.reload(); in your componentDidMount() lifecycle method. If you are using react-router, it has a refresh method to do that.
Edit: If you want to do that after a data update, you might be looking to a re-render not a reload and you can do that by using this.setState(). Here is a basic example of it to fire a re-render after data is fetched.
import React from 'react'
const ROOT_URL = 'https://jsonplaceholder.typicode.com';
const url = `${ROOT_URL}/users`;
class MyComponent extends React.Component {
state = {
users: null
}
componentDidMount() {
fetch(url)
.then(response => response.json())
.then(users => this.setState({users: users}));
}
render() {
const {users} = this.state;
if (users) {
return (
<ul>
{users.map(user => <li>{user.name}</li>)}
</ul>
)
} else {
return (<h1>Loading ...</h1>)
}
}
}
export default MyComponent;
Since React eventually boils down to plain old JavaScript, you can really place it anywhere! For instance, you could place it in a `componentDidMount()' function in a React class.
For your edit, you may want to try something like this:
class Component extends React.Component {
constructor(props) {
super(props);
this.onAddBucket = this.onAddBucket.bind(this);
}
componentWillMount() {
this.setState({
buckets: {},
})
}
componentDidMount() {
this.onAddBucket();
}
onAddBucket() {
let self = this;
let getToken = localStorage.getItem('myToken');
var apiBaseUrl = "...";
let input = {
"name" : this.state.fields["bucket_name"]
}
axios.defaults.headers.common['Authorization'] = getToken;
axios.post(apiBaseUrl+'...',input)
.then(function (response) {
if (response.data.status == 200) {
this.setState({
buckets: this.state.buckets.concat(response.data.buckets),
});
} else {
alert(response.data.message);
}
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
{this.state.bucket}
);
}
}
You can use useNavigate and navigate to the same url you are on. For example, instead of window.location.reload(), you can say navigate("/...your current url....")
window.location.reload() is not the best option everytime. It works on localhost, but for example on when you deploy it to the internet by using services such as "Netlify", it can can cause "not found url" error
Creating some extra state and tracking them for re-rendering your page might unnecessarily complicate your code.
And using useEffect() to re-render your page, again, will unnecesarily complicate your code.
This is my code .This works for me
componentDidMount(){
axios.get('http://localhost:5000/supplier').then(
response => {
console.log(response)
this.setState({suppliers:response.data.data})
}
)
.catch(error => {
console.log(error)
})
}
componentDidUpdate(){
this.componentDidMount();
}
window.location.reload(); I think this thing is not good for react js
use useHistory method in react
import {useHistory} from 'react-router-dom'
const history = useHistory()
history.go(0) // it will refresh particullar page
or use useEffect method
const [data, setData] = useState([])
useEffect(()=>{
setData(reponseApidata)},[data])
//in useEffect dependcy you mention particullar state for you store reposnse data

Categories

Resources