Сейчас пытаюсь изучить React. У меня есть компонент для возврата ряда плакатов на основе некоторых фильтров, как бы мне прочитать длину отрисованного массива плакатов?

Это так, чтобы я мог создать заголовок, такой как «Отображено 6/10 плакатов».

render() {
        return (
            <div className="App">
                <Title />
                    <Posters
                        selectedGenre={this.state.genre}
                        selectedCategory={this.state.category}
                        titles={this.state.titles}
                    />
            </div>
        );
    }

Я подумывал о внедрении функции Posters в render (), чтобы можно было сделать что-то вроде: const posters = this.state.titles.map(title=>...), а затем const filteredPosters = posters.length. Но пытаясь найти способ отделить логику

Спасибо за вашу помощь.

2
neeko 23 Сен 2018 в 16:07

2 ответа

Лучший ответ

Как я отмечал в комментариях, сделайте свой заголовок частью компонента <Posters /> и используйте реквизиты для предоставления общих / отфильтрованных чисел:

class Posters extends React.Component {
  render() {
    const { titles } = this.state;
    const filteredTitles = this.filterTitles(titles);

    return
    <>
      <Header totalSize={titles.length} displayedSize={filteredTitles.length} />
      {filteredTitles.map(title => <Poster title={title} />)}
    </>
  }
}
0
Artyom Neustroev 23 Сен 2018 в 13:21

Я знаю, что на этот вопрос уже был дан ответ, но для будущих зрителей я опубликую еще один способ решения этой проблемы. В примере ниже показано, как отправлять данные из одного компонента в другой, совершенно не связанный компонент. примечание: ищите «Джейк» или «Смит» // HTML // Класс JavaScript Page extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
        logo: '[logoImage]',
      totalPosters: 0,
      filteredPosters: 0,
      activeFilter: ''
    }
  }
  postersUpdated(event) {
    this.state.totalPosters = event.totalPosters;
    this.state.activeFilter = event.filter;
    this.setState({
        filteredPosters: event.filteredPosters,
      totalPosters: event.totalPosters,
      activeFilter: event.filter
    });
  }
  render() {
    return (
      <div className='page'>
        <span>{this.state.logo}</span>
        <Header 
          totalPosters={this.state.totalPosters}
          filteredPosters={this.state.filteredPosters}
          activeFilter={this.state.activeFilter}
          ></Header>
        <Posters ref={this.posters} onChange={this.postersUpdated.bind(this)}></Posters>
      </div>
      )
  }

};
class Header extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
  return (
    <div>
      Results for: "{this.props.activeFilter}":
      {this.props.filteredPosters} /{this.props.totalPosters} 
    </div>)
  }

};

class Posters extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      filter: '',
        posters: [
        { name: "John Smith" },
        { name: "Mike" },
        { name: "Alice" },
        { name: "Jake" }
      ]
    }
    this.setFilter = this.setFilter.bind(this);
  }
  get filteredPosters() {
    return this.state.posters.filter((poster) => {
      if (!this.state.filter || !poster.name) { return; }
      return poster.name.indexOf(this.state.filter) !== -1;
    });
  }
  setFilter(event) {
    this.setState({filter: event.target.value}, () => {
      // send useful info to parent
      // e.g page can show n out of x posters found
      // active search word is "xxx" etc.
      this.props.onChange({
        filteredPosters: this.filteredPosters.length,
        totalPosters: this.state.posters.length,
        filter: this.state.filter
      });
    });
  }
  render() {
    return (
      <div>
        <ol>
        {this.filteredPosters.map(item => (
          <li key={item.id}>
            <label>
              <span>{item.name}</span>
            </label>
          </li>
        ))}
        </ol>
        <input type="text" value={this.state.filter} onChange={this.setFilter} />
      </div>
    )
  }
}

ReactDOM.render(<Page />, document.querySelector("#app"))



// CSS
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

input {
  margin-right: 5px;
}

И скрипка: https://jsfiddle.net/rainerpl/n5u2wwjg/199844/

0
Rainer Plumer 23 Сен 2018 в 14:36