Created
January 12, 2022 00:01
-
-
Save DavidP1983/03cf49f07c1565fe778917cd1ec4c614 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState, useEffect, useRef } from 'react'; | |
// import { HideUntilLoaded } from 'react-animation'; | |
import PropTypes from 'prop-types'; | |
import Spinner from '../spinner/Spinner'; | |
import ErrorMessage from '../errorMessage/ErrorMessage'; | |
import MarvelServices from '../services/MarvelServices'; | |
import './charlist.scss'; | |
const CharList = (props) => { | |
const [charList, setCharList] = useState([]); | |
const [loading, setLoading] = useState(true); | |
const [error, setError] = useState(false); | |
const [newItemLoading, setNewItemLoading] = useState(false); | |
const [offset, setOffset] = useState(1548); | |
const [charEnded, setCharEnded] = useState(true); | |
console.log(offset); | |
const marvelService = new MarvelServices(); | |
useEffect(() => { | |
console.log('updateChar'); | |
updateChar(); | |
}, []); | |
function handleScroll() { | |
if (newItemLoading) return; | |
if (charEnded) { | |
if (window.pageYOffset + document.documentElement.clientHeight >= document.documentElement.scrollHeight) { | |
onCharListLoading(); | |
updateChar(offset); | |
} | |
} | |
} | |
useEffect(() => { | |
console.log('scroll'); | |
window.addEventListener('scroll', handleScroll); | |
return () => { | |
window.removeEventListener('scroll', handleScroll); | |
console.log('unmount'); | |
} | |
}); | |
const updateChar = (offset) => { | |
onCharListLoading(); | |
marvelService.getAllCharacters(offset) | |
.then(onCharListLoaded) | |
.catch(onError) | |
} | |
//loading new items button disable | |
const onCharListLoading = () => { | |
setNewItemLoading(true); | |
} | |
const onCharListLoaded = (newCharList) => { | |
let ended = true; | |
if (newCharList.length < 9) { | |
ended = false; | |
} | |
setCharList(charList => [...charList, ...newCharList]); | |
setLoading(loading => false); | |
setNewItemLoading(newItemLoading => false); | |
setOffset(offset => offset + 9); | |
setCharEnded(charEnded => ended); | |
} | |
const onError = () => { | |
//We use without callback, because we don't mind wich state we have had before | |
setError(true); | |
setLoading(false); | |
} | |
const myRefs = useRef([]); | |
// we use function declaration | |
function renderItems(arr) { | |
const items = arr.map((item, i) => { | |
let imgStyle = { 'objectFit': 'cover' }; | |
if (item.thumbnail === 'http://i.annihil.us/u/prod/marvel/i/mg/b/40/image_not_available.jpg') { | |
imgStyle = { 'objectFit': 'unset' }; | |
} | |
return ( | |
// <HideUntilLoaded key={item.id} animationIn="bounceIn" durationOut={2000}> | |
<li tabIndex={0} | |
//instead of callback function setRef we will do all the stuff inside this map | |
ref={elem => myRefs.current[i] = elem} | |
className="char__item" | |
key={item.id} | |
onClick={() => props.onCharSelected(item.id, myRefs.current[i], myRefs.current)} | |
onFocus={() => props.onCharSelected(item.id, myRefs.current[i], myRefs.current)}> | |
<img src={item.thumbnail} alt={item.name} style={imgStyle} /> | |
<div className="char__name">{item.name}</div> | |
</li> | |
// </HideUntilLoaded> | |
) | |
}); | |
// А эта конструкция вынесена для центровки спиннера/ошибки | |
return ( | |
<ul className="char__grid"> | |
{items} | |
</ul> | |
) | |
} | |
const items = renderItems(charList); | |
const errorMessage = error ? <ErrorMessage /> : null; | |
const spinner = loading ? <Spinner /> : null; | |
const content = !(loading || error) ? items : null; | |
// let name = charEnded ? 'There are no items to load' : 'load more'; | |
// const styleField = { | |
// 'minWidth': '300px', | |
// 'color': 'white', | |
// 'filter': 'grayscale(.5)' | |
// } | |
return ( | |
<div className="char__list"> | |
{errorMessage} | |
{spinner} | |
{content} | |
{/* <button className="button button__main button__long" | |
disabled={newItemLoading} | |
style={{'display': charEnded ? 'none' : 'block'}} | |
// style={charEnded ? styleField : null} | |
onClick={() => updateChar(offset)}> | |
<div className="inner">{name}</div> | |
</button> */} | |
</div> | |
) | |
} | |
CharList.propTypes = { | |
onCharSelected: PropTypes.func.isRequired | |
} | |
export default CharList; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment