State
State can be set as a function or as a state:
this.setState(function(prevState, props){
return { showForm: !prevState.showForm }
});
// либо
this.setState({ showForm: !this.state.showForm });
When setting as state, the function has access to the previous state and props
As a second argument setState can take a callback function:
this.setState(
{ showForm: !this.state.showForm },
() => {
this.myCustomLogger("Состояние компонента изменилось!")
}
);
State changing example:
class CollapsableTextBlock extends React.Component {
state = { toggled: false };
onHeadingClick = () => {
this.setState({toggled: !this.state.toggled})
}
render() {
return (
<div className="CollapsableTextBlock">
<h1 onClick={this.onHeadingClick}>
{this.props.header}
</h1>
{this.state.toggled && <p>{this.props.children}</p>}
</div>
);
}
}
Props drilling: the same code with state handled down to a child component as a prop:
function CollapsableTextContent(props) {
if (!props.toggled) {
return null;
}
return <p>{props.children}</p>
}
class CollapsableTextBlock extends React.Component {
state = { toggled: false };
onHeadingClick = () => {
this.setState({toggled: !this.state.toggled})
}
render() {
return (
<div className="CollapsableTextBlock">
<h1 onClick={this.onHeadingClick}>
{this.props.header}
</h1>
<CollapsableTextContent toggled={this.state.toggled}>
{this.props.children}
</CollapsableTextContent>
</div>
);
}
}
Using spread syntax (...) to modify only some of the state parameters, useful for arrays:
class NewsPanel extends React.Component {
// Состояние компонента
state = {
theme: "светлая",
posts: [
{ id: 1, title: "Новость 1" },
{ id: 2, title: "Новость 2" }
],
commentsEnabled: true,
user: {
name: "Гекльберри Финн",
uuid: "123e4567-e89b-12d3-a456-426655440000",
lastActive: 1614498769824
}
};
// Метод, который отвечает за добавление
addNewPost = () => {
this.setState(prevState => {
// Вычисляем номер добавляемой новости на основании текущего количества
const newPostNumber = prevState.posts.length + 1;
return {
// Сохраняем текущие значения, над которыми не производим действий
...prevState,
posts: [
// Сохраняем текущий список новостей
...prevState.posts,
// Добавляем в список новостей новую запись с вычисленным номером
{
id: prevState.posts.length + 1,
title: `Новость ${newPostNumber}`
}
]
};
});
};
render() {
return <React.Fragment>
<ul>
{this.state.posts.map(post => <li key={post.id}>{`ID#${post.id}: ${post.title}`}</li>)}
</ul>
{/* При нажатии на кнопку будет вызван метод addNewPost */}
<button onClick={this.addNewPost}>Добавить новость</button>
</React.Fragment>;
}
}
#react