My goal is to call the function performSearch () by clicking div in the componentItem. The performSerach () function is placed in another select () function. The select () function is passed to the Item component. In console.log returns me active = null.
Items
class Items extends Component {
constructor (props) {
super(props);
this.state = {
items: [],
active: null,
abc: null
}
}
select = (id) => {
this.setState({
abc: id
})
this.performSearch(id);
}
componentDidMount() {
axios.get
axios({
url,
method: "GET",
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => {
this.setState({
items: res.data
});
})
.catch(error => {
console.log(error);
})
}
performSearch = (id) => {
axios.get
axios({
url: `https://app.com/api/v1/${id}`,
method: "GET",
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(res => {
this.setState({
active: res.data
});
})
.catch(error => {
console.log(error);
})
}
render () {
<div>
{this.state.items.map((item, index) =>
<Item
select={this.select}
/>
)}
</div>
}
}
Item
class Item extends Component {
render () {
return (
<div onClick={()=> this.props.select(this.props.item.id)}>
</div>
)
}
}
render () {
<div>
{this.state.items.map((item, index) =>
<Item
select={this.select}
/>
)}
</div>
}
Should pass the item the Item component:
render () {
<div>
{this.state.items.map((item, index) =>
<Item
select={this.select}
item={item}
key={index}
/>
)}
</div>
}
Or:
render () {
<div>
{this.state.items.map((item, index) =>
<Item
select={() => this.select(item.id)}
/>
)}
</div>
}
Related
sorry i'm new to React. I'm trying to make a basic social network to learn react.
Context:
When i click on the "like" button, the setState should call the function to update the state of my component, but it is updated only when i refresh the page. I think the ComponentDidUpdate function isn't called like it should. What did i do wrong? Thanks for your help!
Here are the parts of the code :
Like button component:
class Like_Button extends React.Component {
constructor(props) {
super(props);
this.state = {liked : "Like"};
}
isliked(){
fetch("likes_of_user/")
.then(res => res.json())
.then((result) => {
result.map(x => {if(this.props.pk == x.liked_post){this.setState({liked: "Unlike"});}});
})
}
componentDidMount() {
this.isliked();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.liked !== this.state.liked) {
this.isliked();
}
}
render() {
return (
<button className = "buttons" onClick={() => {
var csrftoken = getCookie('csrftoken');
fetch(`like_post/${this.props.pk}`, {method: "POST", headers: {'Accept': 'application/json', 'Content-Type': 'application/json','X-CSRFToken': csrftoken}})
}}>{this.state.liked}</button>
)
}
}
Newsfeed component:
class Newsfeed_comp extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}
componentDidMount() {
fetch("get_newsfeed/")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result
});
},
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map((item ,index) => (
<li className="postbox" key={`${item}${index}`}>
{item.author}
{item.date}
{item.content}
<Like_Button pk={item.id} />
</li>
))}
</ul>
);
}
}
}
ReactDom render:
ReactDOM.render(<Newsfeed_comp />, document.getElementById("newsfeed_view"))
Try something like this:
LikeButton.js
import React, { useEffect, useState } from 'react';
export default function LikeButton({ pk }) {
const [like, setLike] = useState(false);
useEffect(() => {
const fetchLike = async () => {
const res = await fetch("likes_of_user/");
const result = await res.json();
if (result.length > 0) {
setLike(result.find(item => item.liked_post === pk));
}
};
try {
fetchLike();
} catch (error) {
// handle error
}
});
const handleClick = async () => {
const csrftoken = getCookie('csrftoken');
return fetch(`like_post/${pk}`, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
method: 'POST',
});
};
return (
<button className='buttons' onClick={handleClick}>
{like}
</button>
);
};
NewsFeed.js
import React, { useEffect, useState } from 'react';
export function NewsFeed() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
useEffect(() => {
const getNewsFeed = async () => {
const res = await fetch('get_newsfeed/');
const result = await res.json();
setIsLoaded(true);
setItems(result);
};
try {
getNewsFeed();
} catch (error) {
setIsLoaded(true);
setError(error);
}
});
if (error) return <div>Error: {error.message}</div>;
if (isLoaded) return <div>Loading...</div>;
const list = items.map((item) => (
<li className='postbox' key={item.content}>
{item.author}
{item.date}
{item.content}
<LikeButton pk={item.id} />
</li>
));
return <ul>{list}</ul>;
};
App.js
ReactDOM.render(<NewsFeed />, document.getElementById('newsfeed_view'));
Looks like you've reversed your logic, i.e. your button directly updates the data in the backend but does nothing to update component state, so the componentDidUpdate isn't called as you've seen. The refresh is required so the component is remounted and the componentDidMount can fetch the likes data.
Try instead to update local state first, then use componentDidUpdate to issue the side-effect of updating the backend.
constructor(props) {
super(props);
this.state = { liked: true };
}
isliked() {
fetch("likes_of_user/")
.then(res => res.json())
.then((result) => {
result.map(x => {
if (this.props.pk === x.liked_post) {
this.setState({ liked: false });
}
});
})
}
componentDidUpdate(prevProps, prevState) {
if (prevState.liked !== this.state.liked) {
const csrftoken = getCookie('csrftoken');
fetch(
`like_post/${this.props.pk}`,
{
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
},
}
);
}
}
<button
className="buttons"
onClick={() => this.setState(
prevState => ({ liked: !prevState.liked })
)}
>
{this.state.liked ? "Liked" : "Unliked"}
</button>
The below code renders a list of planets (from this API: https://swapi.dev/).I'm trying to find a way to make my planets clickable. When a specific planet is clicked in the list, it should open up a detail page with specific info (pulled from API) on the planet that has been clicked. Can I do this with or ? What is the best practice way to do this?
import React, { PureComponent } from 'react'
import axios from "axios";
class Home extends PureComponent {
constructor(props) {
super(props)
this.state = {
planets: [],
filteredPlanets: []
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(e){ // eslint-disable-next-line
let planetssearchlist = this.state.planets.filter(planet => {
if(planet.name){
if(planet.name.toLowerCase().includes(e.target.value.toLowerCase())){
return true
}
}
})
this.setState({
filteredPlanets: planetssearchlist
})
}
componentDidMount(){
axios({
method: "GET",
url: "https://swapi.dev/api/planets/"
})
.then(response => {
console.log(response)
let planetslist = response.data.results;
this.setState({planets: planetslist, filteredPlanets: planetslist})
})
.catch(error => {
console.log("You've made an error with the planets load charles: ",error)
})
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input placeholder="searchbar" type="text" onChange={this.handleChange}></input>
</form>
{
this.state.filteredPlanets.map((planet,i) => (
<p key={i}>{planet.name}</p>
))
}
</div>
)
}
}
export default Home
Add a new function to get the planet info. In your map add onClick event handler to get the planet info for the clicked planet.
Add two new variable to your state
this.state = {
planets: [],
filteredPlanets: [],
planetInfo: {},
isGettingPlanetInfo: false,
};
Add a function to get the planet info
getPlanetInfo = url => {
this.setState({
isGettingPlanetInfo: true
})
axios({
method: "GET",
url: url
})
.then(response => {
console.log(response.data)
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false,
})
})
.catch(error => {
this.setState({
isGettingPlanetInfo: false
})
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
Add on click event handler to the planet
{this.state.filteredPlanets.map((planet, i) => (
<p onClick={() => this.getPlanetInfo(planet.url)} key={i}>
{planet.name}
</p>
))}
Home component
import React, { PureComponent } from 'react';
import axios from 'axios';
export default class Home extends PureComponent {
constructor(props) {
super(props);
this.state = {
planets: [],
filteredPlanets: [],
planetInfo: {},
isGettingPlanetInfo: false,
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
// eslint-disable-next-line
let planetssearchlist = this.state.planets.filter((planet) => {
if (planet.name) {
if (planet.name.toLowerCase().includes(e.target.value.toLowerCase())) {
return true;
}
}
});
this.setState({
filteredPlanets: planetssearchlist,
});
}
getPlanetInfo = (url) => {
this.setState({
isGettingPlanetInfo: true,
});
axios({
method: 'GET',
url: url,
})
.then((response) => {
console.log(response.data);
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false,
});
})
.catch((error) => {
this.setState({
isGettingPlanetInfo: false,
});
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
componentDidMount() {
axios({
method: 'GET',
url: 'https://swapi.dev/api/planets/',
})
.then((response) => {
console.log(response);
let planetslist = response.data.results;
this.setState({ planets: planetslist, filteredPlanets: planetslist });
})
.catch((error) => {
console.log(
"You've made an error with the planets load charles: ",
error
);
});
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input
placeholder='searchbar'
type='text'
onChange={this.handleChange}
/>
</form>
{this.state.filteredPlanets.map((planet, i) => (
<p onClick={() => this.getPlanetInfo(planet.url)} key={i}>
{planet.name}
</p>
))}
<hr />
{this.state.isGettingPlanetInfo ? (
<p>getting planet info...</p>
) : typeof this.state.planetInfo === 'object' &&
Object.keys(this.state.planetInfo).length ? (
<div>
<p>name: {this.state.planetInfo.name}</p>
<p>climate: {this.state.planetInfo.climate}</p>
<p>population: {this.state.planetInfo.population}</p>
</div>
) : (
''
)}
</div>
);
}
}
With react router
import React, { PureComponent } from "react";
import axios from "axios";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
class PlanetInfo extends React.Component {
state = {
url: "",
planetInfo: {},
isGettingPlanetInfo: false
};
getPlanetInfo = () => {
this.setState({
isGettingPlanetInfo: true
});
axios({
method: "GET",
url: this.state.url
})
.then(response => {
console.log(response.data);
this.setState({
planetInfo: response.data,
isGettingPlanetInfo: false
});
})
.catch(error => {
this.setState({
isGettingPlanetInfo: false
});
console.log(
"You've made an error with the planets load charles: ",
error
);
});
};
componentDidMount = () => {
this.setState(
{
url: this.props.location.state.planet.url
},
this.getPlanetInfo
);
};
render() {
return (
<div>
{this.state.isGettingPlanetInfo ? (
<p>getting planet info...</p>
) : typeof this.state.planetInfo === "object" &&
Object.keys(this.state.planetInfo).length ? (
<div>
<p>name: {this.state.planetInfo.name}</p>
<p>climate: {this.state.planetInfo.climate}</p>
<p>population: {this.state.planetInfo.population}</p>
</div>
) : (
""
)}
</div>
);
}
}
class Home extends PureComponent {
constructor(props) {
super(props);
this.state = {
planets: [],
filteredPlanets: []
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
// eslint-disable-next-line
let planetssearchlist = this.state.planets.filter(planet => {
if (planet.name) {
if (planet.name.toLowerCase().includes(e.target.value.toLowerCase())) {
return true;
}
}
});
this.setState({
filteredPlanets: planetssearchlist
});
}
componentDidMount() {
axios({
method: "GET",
url: "https://swapi.dev/api/planets/"
})
.then(response => {
console.log(response);
let planetslist = response.data.results;
this.setState({ planets: planetslist, filteredPlanets: planetslist });
})
.catch(error => {
console.log(
"You've made an error with the planets load charles: ",
error
);
});
}
render() {
return (
<div>
<h1>Star Wars Planets</h1>
<form>
<input
placeholder="searchbar"
type="text"
onChange={this.handleChange}
/>
</form>
{this.state.filteredPlanets.map((planet, i) => (
<Link to={{ pathname: "/info", state: { planet: planet } }}>
<p key={i}>{planet.name}</p>
</Link>
))}
</div>
);
}
}
export default function Navigation() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/info" component={PlanetInfo} />
</Switch>
</BrowserRouter>
);
}
so I am currently working on an admin control panel for a page that displays a list of card. The cards contain details passed on from a local API that is hosted with a range of data such as "id", "title", "URL" and "ThumbnailUrl" and this is obtained from "localhost:0000/videos".
So I have a module, one that creates the Card called HelpCard.tsx and the code is as follows:
import React, { Component } from "react";
import "../help/HelpCardTwo.css";
import "../help/HelpList";
import Popup from "reactjs-popup";
import spinner from "../help/spinner.gif";
import placeholder from "../help/placeholder.jpeg";
interface Props {
id: string;
url: string;
title: string;
thumbnail: string;
deleteProduct: (id: any) => void;
editProduct: (id: any, title: string, url: string, thumbnail: string) => void;
}
interface State {
title: string;
thumbnail: string;
id: string;
url: string;
imageLoading?: boolean;
tooManyRequests?: boolean;
}
export default class HelpCard extends Component<Props, State> {
state = {
url: "",
id: "",
title: "",
imageLoading: true,
tooManyRequests: false,
thumbnail: ""
};
componentDidMount() {
const { url, title, thumbnail } = this.props;
const id = url.split("/")[url.split("/").length - 2];
this.setState({
url,
id,
title,
thumbnail,
imageLoading: true,
tooManyRequests: false
});
}
render() {
const isThumbnail = this.state.thumbnail;
const adminhelpcard = this.state;
return (
<React.Fragment>
<div className="cards">
<article className="card card--2">
<div className="card__info-hover"></div>
<div className="card__img">
{this.state.imageLoading ? <img src={placeholder} style={{ width: "100%", height: "100%" }}></img> : null}
<img
className="Sprite"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ tooManyRequests: false })}
src={this.state.thumbnail}
/>
</div>
<div className="card__info">
<span className="card__category">{this.state.title}</span>
<div className="cardButtons">
<Popup trigger={<button className="btn blue-outline">Edit</button>} modal position="left top">
<form
onSubmit={(e) => e.preventDefault()}
id="videoCardEdit"
style={{ width: "auto", height: "auto" }}>
<div>
<div>
<label>Title:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardTitle"
onChange={(e) => {
this.setState({ title: e.target.value });
}}
value={this.state.title}></input>
</div>
<div>
<label>URL:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardURL"
onChange={(e) => {
this.setState({ url: e.target.value });
}}
value={this.state.url}></input>
</div>
<div>
<label>Thumbnail URL:</label>
<input
className="input"
style={{ width: "100%" }}
name="videoCardThumbnail"
onChange={(e) => {
this.setState({ thumbnail: e.target.value });
}}
value={this.state.thumbnail}></input>
</div>
<br></br>
</div>
<button
className="btn blue-outline"
style={{
float: "left"
}}
onClick={() =>
this.props.editProduct(this.props.id, this.state.title, this.state.url, this.state.thumbnail)
}
id="btn blue-outline">
confirm
</button>
</form>
</Popup>
<button onClick={() => this.props.deleteProduct(this.props.id)} className="btn blue-outline">
Delete
</button>
</div>
</div>
</article>
</div>
</React.Fragment>
);
}
}
I then also have HelpList.tsx that has the following code:
import React, { Component } from "react";
import HelpCard from "./HelpCard";
import "../help/HelpCard.css";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
interface State {
url: string;
title: string;
adminhelpcard: SingleAdminHelpCard[];
error: null;
response: {};
thumbnail: string;
}
interface SingleAdminHelpCard {
id: string;
url: string;
title: string;
thumbnail: string;
}
interface Props {}
export default class HelpList extends Component<Props, State> {
state = {
title: "",
thumbnail: "",
id: "",
url: "http://localhost:3000/videos/",
adminhelpcard: [],
itemsCountPerPage: 1,
activePage: 1,
error: null,
response: {}
};
loadAdminHelpCard = () => {
axios
.get(this.state.url)
.then((res) => {
this.setState((prevState) => {
const adminhelpcard = prevState.adminhelpcard;
return {
adminhelpcard: [...prevState.adminhelpcard, ...res.data],
url: res.data.next
};
});
})
.catch(function(error) {
// handle error
console.log(error);
});
};
static props: any;
async componentDidMount() {
const apiVideoUrl = "http://localhost:3000/videos/";
const apiManualUrl = "http://localhost:3000/manuals/";
const res = await axios.get(this.state.url);
this.setState({ adminhelpcard: res.data });
fetch(apiVideoUrl)
.then((res) => res.json())
.then(
(result) => {
this.setState({
adminhelpcard: result
});
},
(error) => {
this.setState({ error });
}
);
fetch(apiManualUrl)
.then((res) => res.json())
.then(
(result) => {
this.setState({
adminhelpcard: result
});
},
(error) => {
this.setState({ error });
}
);
}
deleteProduct(id: any) {
const { adminhelpcard } = this.state;
const apiVideoUrl = `http://localhost:3000/videos/${id}`;
const apiManualUrl = `http://localhost:3000/manuals/${id}`;
const options = {
method: "DELETE"
};
fetch(apiVideoUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);
fetch(apiManualUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);
console.log(this.state.id);
}
editProduct(id: any, title: string, url: string, thumbnail: string) {
const { adminhelpcard } = this.state;
const apiVideoUrl = `http://localhost:3000/videos/${id}`;
const apiManualUrl = `http://localhost:3000/manuals/${id}`;
const options = {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title,
url,
thumbnail
})
};
fetch(apiVideoUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);
fetch(apiManualUrl, options)
.then((res) => res.json())
.then(
(result) => {
this.setState({
response: result,
adminhelpcard: adminhelpcard.filter((adminhelpcard: SingleAdminHelpCard) => adminhelpcard.id !== id)
});
},
(error) => {
this.setState({ error });
}
);
}
render() {
console.log(this.state.adminhelpcard);
return (
<div>
<React.Fragment>
{this.state.adminhelpcard ? (
<div className="row">
<InfiniteScroll
pageStart={1}
loadMore={this.loadAdminHelpCard}
hasMore={this.state.url ? true : false}
threshold={0}
loader={
<div className="loader" key={0}>
Loading ...
</div>
}>
{this.state.adminhelpcard.map((adminhelpcard: SingleAdminHelpCard, i) => (
<HelpCard
id={adminhelpcard.id}
key={adminhelpcard.id + i}
title={adminhelpcard.title}
url={adminhelpcard.url}
thumbnail={adminhelpcard.thumbnail}
deleteProduct={this.deleteProduct.bind(this)}
editProduct={this.editProduct.bind(this)}
/>
))}
</InfiniteScroll>
</div>
) : (
<h1>Loading Cards</h1>
)}
</React.Fragment>
</div>
);
}
}
So I created these two classes to obtain all the information from localhost:0000/videos before realizing theres also localhost:0000/texts which also send the same data such as "Id, title, URL, thumbnailUrl". How can I go about loading all the cards from both urls simultaneosly? The list now only seems to bring in /texts cards and not both together.
The easiest way to do that is to use a Promise.all(getVideos(),getTexts()). Assuming getVideos() and getTexts() are methods that are returning promises like so:
async function getVideos() {
const res = await fetch('http://localhost:3000/videos/')
return await res.json();
}
async function getText() {
const res = await fetch('http://localhost:3000/texts/')
return await res.json();
}
Promise.all(getVideos(), getTexts()).then(data = {
const [ videos, texts ] = data;
// all data arrived at the same time
})
I would imagine your componentDidMount to look like this:
async componentDidMount() {
const apiVideoUrl = "http://localhost:3000/videos/";
const apiManualUrl = "http://localhost:3000/manuals/";
const getVideos = async() => {
return await axios.get(apiVideoUrl);
}
const getManuals = async() => {
return await axios.get(apiManualUrl);
}
try {
const [videos, manuals] = await Promise.all(getVideos(), getManuals());
// render to state setState({ prop: ? })
} catch(err) {
this.setState({ error });
}
}
not sure why you have two fetch calls in edit and delete, it looks like the calls are overwriting each other?
I'm working with react, redux-form and laravel.
I have created a form to be able to insert notes in the database but when I show the Request in laravel an empty array always appears.
I do not know what I'm doing wrong.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
notes: [],
};
this.submitToServer = this.submitToServer.bind(this)
this.submit = this.submit.bind(this)
}
componentWillMount() {
fetch('http://127.0.0.1:8000/notes')
.then(res => res.json())
.then(json => json.results)
.then(notes => this.setState({ notes }))
.catch(console.log)
}
async submitToServer(data) {
let response = await fetch('http://127.0.0.1:8000/notes', {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(data)
})
let responseJSON = await response.json()
return responseJSON
}
submit({ title, content }) {
this.submitToServer({ title, content })
.then(res => this.setState(prevState => ({
notes: [...prevState.notes, {
id: prevState.notes.pop().id + 1,
title: title,
content: content
}]
})))
}
render() {
if (this.state.notes.length > 0) {
return (
<div>
<h1>Notas</h1>
<Paper>
<form onSubmit={this.props.handleSubmit(this.submit)}>
<Field name="title" label="Title" component={renderField} type="text" />
<Field name="content" label='Content' component={renderField} type="text" />
<button type="submit">Submit</button>
</form>
</Paper>
))}
</div>
)
} else {
return <p>Cargando notas...</p>
}
}
}
In laravel at the moment I'm just returning the Request to show what it contains.
public function storeNote(Request $request) {
return $request;
}
How to make load more with FlatList of React Native (Not infinite)
I've done this, but unfortunately it loads as infinitely.
This is my code snippet
<FlatList
data={this.props.data}
renderItem={({ item, separators }) => (
<TouchableHighlight
onPress={() => this._onPress(item)}
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}
>
<Text> {item.title} </Text>
</TouchableHighlight>
)}
keyExtractor={item => item.id}
ListFooterComponent={this.renderFooter}
onEndReached={this.props.handleLoadMore}
onEndThreshold={0}
/>
And my handleLoadMore
handleLoadMore = () => {
console.log("test"); // <---- this line run infinitely
fetch(url, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(filters)
})
.then(response => response.json())
.then(responseJson => {
this.setState({
itemData: [
...this.state.itemData,
...responseJson.estate_list
],
itemPage: this.state.itemPage + 1
});
})
.catch(error => {
console.error(error);
});
};
There is issue when loading data in FlatList and your onEndReached handler will be called when the view is re-rendered. Try setting a flag like this :
constructor(props){
super(props);
this.state = {
hasScrolled: false
}
}
Then add this method :
onScroll = () => {
this.setState({hasScrolled: true})
}
Hook it up to FlatList:
<FlatList
onScroll={this.onScroll}
Finally load only when scrolled :
handleLoadMore = () => {
if(!this.state.hasScrolled){ return null; }
//here load data from your backend
}
constructor(props){
super(props);
this.state = {
loading: true
}
}
<FlatList
onEndReached={this.handleLoadMore}/>
handleLoadMore = () => {
if(!this.state.loading){ return null; }
this.setState({
page: this.state.page + 1,
loading: false
}, () => {
this.loadProducts();
});
};
loadProducts(catId,userkey){
$this.setState({
loading:true
});
}