-
-
Save silavsale/4e25c0792ece74d172b70e709ae7d0b4 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