@PlasterTom

Как правильно использовать react component?

Подключаю react-masonry-infinite.
Базовое использование компонента выглядит так:
<MasonryInfiniteScroller
    hasMore={this.state.hasMore}
    loadMore={() => this.setState({ elements: this.state.elements.push("Element") })}
>
    {
        this.state.elements.map(id =>
            <div key={id} />
        )
    }
</MasonryInfiniteScroller>


Как должна выглядеть строка this.state.elements.map, если

const elements = [
{      
            id: 1,
            thumbnail: "https://c5.staticflickr.com/9/8768/28941110956_b05ab588c1_n.jpg",
            thumbnailWidth: 300,
            thumbnailHeight: 320
        },
        {   
            id: 2,
            thumbnail: "https://c3.staticflickr.com/9/8583/28354353794_9f2d08d8c0_n.jpg",
            thumbnailWidth: 320,
            thumbnailHeight: 190
        },
        {
             id: 3,
            thumbnail: "https://c7.staticflickr.com/9/8569/28941134686_d57273d933_n.jpg",
            thumbnailWidth: 320,
            thumbnailHeight: 148
        }, и т.д.
]


И так же непонятно, что нужно сделать со строкой loadMore={() => this.setState({ elements: this.state.elements.push("Element") })}
Что за "Element"?
  • Вопрос задан
  • 96 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
1. Функция map превращает в колбеке элемент вашего массива данных в JSX код описывающий элемент и на выходе выдает массив таких элементов. Это лучший и общепринятый способ рендерить списки в react.
Банальный пример:
const employees =  ['Bill', 'Matt', 'Sarah'];

return (
  <ul>
    {employees.map((employee, i) => (
      <li key={i}>employee</li>
    )}
  <ul>
);

Результат:
<ul>
  <li>Bill</li>
  <li>Matt</li>
  <li>Sarah</li>
</ul>


2. "Element" как видите строка. Тут разработчики просто пушат в массив строку, но в идеале тут должна вызываться функция иницирующая запрос к серверу.
Вот более приближенный к жизни пример:
class Example extends Component {
  state = {
    elements: [],
    page: 1,
    limit: 20,
    total: 0,
    isLoading: false,
    isError: false,
  };
  
  componentDidMount() {
    this.loadThumbnails();
  }
 
  loadThumbnails = () => {
    const { page, limit } = this.state;
    
    this.setState({
      isLoading: true,
      isError: false,
    }, () => {
      axios.get(
        `api/somePath?limit=${limit}&page=${page + 1}`
      ).then(response => {
        const { data: { elements, total } } = response;
      
        this.setState(prevState => ({
          elements: [
            ...prevState.elements,
            ...elements
          ],
          page: page + 1,
          isLoading: false,
          total,
        }));
      }).catch(error => {
        this.setState({
          isLoading: false,
          isError: true,
        });
      });
    });
  };
  
  render() {
    const {
      elements,
      page,
      limit,
      total,
      isLoading,
    } = this.state;

    const hasMore = page * limit < total;

    return(
      <MasonryInfiniteScroller
        hasMore={hasMore}
        loadMore={this.loadThumbnails}
      >
        {elements.map(element => (
          <img
            key={element.id}
            src={element.thumbnail}
            style={{
              width: element.width + 'px',
              height: element.height + 'px',
            }}
          />
        )}
        {isLoading && <div>...Loading</div>}
        {isError && (
          <div>
            Can't load data. Please, check your internet connection.
            <button onClick={this.loadThumbnails}>
              Try again
            </button>
          </div>
        )}
      </MasonryInfiniteScroller>
    ); 
  }
}


Тут как только вы пролистнете список
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы