В этом посте я объясню, как передавать состояние между компонентами в Reactjs. Мы создадим небольшое приложение Сколько книг вы прочитали?, в этом приложении у нас есть два основных компонента: один большой под названием Библиотека и другой маленький Книга, у нас есть 3 книги в состоянии библиотеки, и каждая книга имеет свое государство. проверьте любую книгу, чтобы считать ее прочитанной. попробовать приложение здесь

Начнем с кода:

Передача состояния от родителя к дочернему

В нашем компоненте библиотеки у нас есть это состояние

this.state = {
	reads: 0,
	books: [
		{
			name: 'Zero to one',
			isbn: '9780804139298',
			author: 'Peter Thiel',
			cover: 'https://images.gr-assets.com/books/1414347376l/18050143.jpg',
			status: false
		},
		{
			name: "The Manager's Path",
			isbn: '9781491973899',
			author: 'Camille Fournier',
			cover: 'https://images.gr-assets.com/books/1484107737l/33369254.jpg',
			status: false
		},
		{
			name: 'Calculus, Better Explained',
			isbn: '9781470070700',
			author: 'Kalid Azad',
			cover: 'https://images.gr-assets.com/books/1448590460l/27993945.jpg',
			status: false
		}
	]
};

и хотите создать this.state.books.length — в виде числа — Book компонентов, каждый из которых имеет свойства из массива books состояния Libraryкомпонента. Мы должны иметь дело с двумя компонентами.

Сначала с родителем мы должны создать компонент Book this.state.books.length - в виде числа - раз и передать им наши разные значения. Вот так:

Полный код здесь

{
	this.state.books.map((_book, _id) => {
		return (
			<Book
				handleCounter={this.handleCounter}
				key={_id}
				id={_book.isbn}
				name={_book.name}
				isbn={_book.isbn}
				author={_book.author}
				cover={_book.cover}
			/>
		);
	});
}

Примечание пока игнорируйте handleCounter.

Во-вторых с дочерним элементом Book, у нас есть значения от родителя, давайте использовать их:

Полный код здесь

...
render() {
	return (
		<Card>
			<Image
				src={this.props.cover}
    			alt="Book cover"
...

До сих пор мы создали 3 компонента Book из родительского компонента Library и устанавливали их значения из родительского состояния. Легкий! Правильно? Отлично, начинаем вторую часть

Передача состояния от дочернего к родительскому

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

В нашем Book у нас есть это состояние

Полный код здесь

this.state = {
	status: false,
	id: this.props.id
};

Примечание не забудьте передать props конструктору компонента.

status означает, читали ли вы эту книгу или нет, и его значение по умолчанию — false, id — это идентификатор этой книги, и я установил его по идентификатору книги, как мы узнали в предыдущем разделе.

нам нужно обработать изменение этого статуса, а затем обновить массив книг в родительском состоянии.

В нашем компоненте Book мы добавим флажок, который получает изменение статуса книги и передает this.handleChange его onChangeсобытию следующим образом:

Полный код здесь

<input type="checkbox" name="example" onChange={this.handleChange} />

вам нужно сначала связать функцию, затем обновить состояние Book с новым статусом, после обновления дочернего состояния мы обновим состояние родителя Library следующим образом:

Полный код здесь

handleChange() {
		this.setState({status: !this.state.status}, this.updateLibraryCount);
    }
updateLibraryCount() {
		this.props.handleCounter(this.state);
	}

В updateLibraryCount мы использовали handleCounter функцию Library в качестве реквизита, затем передали ей состояние Book. Теперь Library видит состояние Book, отлично! давайте использовать его.

Полный код здесь

handleCounter(_State) {
        //Get the index of this book by searching by its unique isbn
        const ObjNum = this.state.books.findIndex(
			_book => _book.isbn === _State.id
        );
        //then update its value in the Library component
		this.setState(
			{
				books: update(
					ObjNum,
					{...this.state.books[ObjNum], status: _State.status},
					this.state.books
				)
			},
			() => {
                //this is a callback to handle the new change of the book status and increment the reads
				const _read = this.state.books.filter(_book => _book.status === true)
					.length;
				this.setState({reads: _read});
			}
		);
	}

Надеюсь, вы понимаете, как передать состояние от родителя к дочернему и наоборот. Вот полный код, а это оригинальный пост в моем блоге. Если у вас есть вопросы, не стесняйтесь задавать их в комментариях или электронной почте.