ReactJS - массив и его модификация через props

118
15 июня 2019, 09:30

Не понимаю как сделать сортировку книг. В родительском блоке создал массив со всеми данными книгами, а дальше не понимаю как по нажатию на кнопки (всего их 4 и каждая модифицирует массив по своему: одна отображает его полностью, вторая сортирует по рейтингу, третья по популярности и четвертая выводит только бесплатные книги) в одном child-компоненте, передавать этот модифицированный массив в другой child-компонент. Я новичок в этом деле и не понимаю пока как это реализовать...

Answer 1

Так как кода вы не привели в вопросе, то и ответ будет основан на рекомендациях с минимумом кода. Итак, предположим, что есть родительский компонент, где есть массив со всеми книгами (банальный и простой пример, allBooks - все книги (оригинальный массив), filteredBooks - отфильтрованный массив книг, предположим, что через пропсу сюда попадает весь список книг):

const books = [
  { ID: 1, Name: 'One', Author: 'Remark' },
  { ID: 2, Name: 'Two', Author: 'Burunov' },
  { ID: 3, Name: 'Three', Author: 'Romanov' },              
],

Предположим, что у нас есть некий набор книг, где лежат объекты, описывающие книги и этот массив передается через пропсу books в родительский компонент, ну либо внутри componentDidMount загружается откуда, то, но смыл простой, мы проинициализируем наши переменные в стейте родителя:

class ParrentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      allBooks: props.books,
      filteredBooks: props.books, // изначально можно пустой массив `[]`
    }
    // some code here...
  }
  // some code here...
}

Предположим, что у нас есть свои методы фильтрации, можно и справочник завести (в случае с Redux было бы удобнее), и эти методы также будут лежать в родительском компоненте, для примера напишу пару штук:

showAllBooks() {
  const { allBooks } = this.state;
  this.setState({ filteredBooks: allBooks });
}
filterByName(name) {
  const { allBooks } = this.state;
  const filteredBooks = allBooks.filter(book => book.Name === name)
  this.setState({ filteredBooks });
}
filterByAuthor(author) {
  const { allBooks } = this.state;
  const filteredBooks = allBooks.filter(book => book.Author === author)
  this.setState({ filteredBooks });
}

Обрашу ваше внимание на то, что метод Array.prototype.filter() создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции, что является безопасным подходом и не вызовет мутации состояния.

Теперь перейдем к вашим чаилд компонентам. Первый, как я понимаю там кнопки с фильтрами, точнее по нажатию на кнопки будет происходить отображение того или иного массива. Передадим в этот чаилд компонент ссылки на наши методы. Второй - будет содержать пропсу с отфильтрованным списком.

<ChildWithButtons
  showAllBooks={this.showAllBooks}
  filterByName={this.filterByName}
  filterByAuthor={this.filterByAuthor}
/>
<ChildWithFilteredBooks
  filteredBooks={this.state.filteredBooks}
/>    

Внутри этого компонента навесим обработчкик кликов на кнопки, для примера кусочек из рендера и обработка для одной кнопки (для других по подобию):

<button onClick={this.filterByName}>Filter by name</button>

в этом же компоненте будет свой обработчик этого клика и вызов из него метода фильтрации через пропсу.

filterByName(event) {
  const name = 'One'; // для примера будет такое имя, его можно брать откуда угодно
  this.props.filterByName(name); // вызовем метод фильтрации из пропсы
}

После клика по кнопке вызовется метод из пропсы, отфильтруется массив и обновится второй чаилд компонент, который использует отфильтрованный массив, так как обновится его пропса filteredBooks. Вот так, посредством props из одного родительского компонента можно произвести общение между двумя его дочерними компонентами. Обратите внимание, что оригинальный массив allBooks мы не меняем, а используем его как источник для фильтрации. Не забываем про байндинги внутри конструктора, если вдруг нужен this, а он нужен.

Также будет полезно почитать:

  • React.Component
  • Components and Props
  • State and Lifecycle
READ ALSO
Неверно определяется isAutoplayAllowed

Неверно определяется isAutoplayAllowed

Есть такая проблема - у хрома новая политика безопасности, которая блокирует автовоспроизведение видео, если не было взаимодействия пользователя...

89
Отнять от даты 1 день

Отнять от даты 1 день

есть дата 2018-11-12 как от нее отнять 1 день в js? urrDatesetDate(CurrDate

116
Проблема с nodeJS и регистрацией через mysql

Проблема с nodeJS и регистрацией через mysql

у меня возникла странная, как мне сейчас кажется, проблемаДо этого с базами я не работал, поэтому прошу помощи у специалистов!

133