P
P
PlasterTom2018-01-31 23:23:20
JavaScript
PlasterTom, 2018-01-31 23:23:20

How to use react component correctly?

I include react-masonry-infinite.
The basic usage of the component looks like this:

<MasonryInfiniteScroller
    hasMore={this.state.hasMore}
    loadMore={() => this.setState({ elements: this.state.elements.push("Element") })}
>
    {
        this.state.elements.map(id =>
            <div key={id} />
        )
    }
</MasonryInfiniteScroller>

What should the this.state.elements.map line look like if
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
        }, и т.д.
]

And it's also not clear what to do with the line loadMore={() => this.setState({ elements: this.state.elements.push("Element") })}
What is "Element"?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2018-01-31
@PlasterTom

1. The map function turns an element of your data array into JSX code describing the element in a callback and produces an array of such elements at the output. This is the best and generally accepted way to render lists in react .
Banal example:

const employees =  ['Bill', 'Matt', 'Sarah'];

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

Result:
<ul>
  <li>Bill</li>
  <li>Matt</li>
  <li>Sarah</li>
</ul>

2. "Element" as you can see a string. Here, the developers simply push a string into the array, but ideally, a function that initiates a request to the server should be called here.
Here is a more realistic example:
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>
    ); 
  }
}

Here, as soon as you scroll through the list

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question