В настоящее время я изучаю концепцию хуков в React и пытаюсь понять приведенный ниже пример.
import { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick = {() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
В приведенном выше примере увеличивается значение счетчика самого параметра функции-обработчика. Что, если я хочу изменить значение счетчика внутри функции обработчика событий
Рассмотрим пример ниже:
setCount = () => {
//how can I modify count value here. Not sure if I can use setState to modify its value
//also I want to modify other state values as well here. How can I do that
}
<button onClick = {() => setCount()}>
Click me
</button>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Хуки - это новая функция в React v16.7.0-alphauseState - это «Крючок». useState() устанавливает значение по умолчанию для любой переменной и управляет функциональным компонентом (функции PureComponent). ex : const [count, setCount] = useState(0); устанавливает значение по умолчанию для счетчика 0. u может использовать значение от setCount до increment или decrement. onClick = {() => setCount(count + 1)} увеличивает значение счетчика.
Синтаксис ловушки useState прост.
const [value, setValue] = useState(defaultValue)
Если вы не знакомы с этим синтаксисом, перейдите здесь.
Я бы порекомендовал вам прочитать документация. Там есть отличные объяснения с приличным количеством примеров.
import { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
// its up to you how you do it
const buttonClickHandler = e => {
// increment
// setCount(count + 1)
// decrement
// setCount(count -1)
// anything
// setCount(0)
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick = {buttonClickHandler}>
Click me
</button>
</div>
);
}Это должен быть принятый ответ. Кратко и ясно, с хорошими внешними ссылками.
Это наихудший ответ, в основном скопируйте / вставьте страницу документа. Я пришел сюда, потому что страница документа сбивала с толку
Что вас смущает, друг мой? Лучшего объяснения, чем в официальной документации, не найти.
Реагировать на хуки - это новый способ (все еще разрабатываемый) для доступа к основным функциям реакции, таким как state, без использования классов, в вашем примере, если вы хотите увеличить счетчик непосредственно в функции обработчика, не указывая его непосредственно в опоре onClick, вы могли бы сделать что-то вроде:
...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...
const setCount = () => {
setCounter(count + 1);
setMoreStuff(...);
...
};
и onClick:
<button onClick = {setCount}>
Click me
</button>
Давайте быстро объясним, что происходит в этой строке:
const [count, setCounter] = useState(0);
useState(0) возвращает кортеж, в котором первый параметр count - это текущее состояние счетчика, а setCounter - метод, который позволит нам обновить состояние счетчика. Мы можем использовать метод setCounter для обновления состояния count где угодно - в этом случае мы используем его внутри функции setCount, где мы можем делать больше; идея с хуками состоит в том, что мы можем сохранить наш код более функциональным и избегать компоненты на основе классов, если он не желателен / необходим.
Я написал полную статью о хуках с множеством примеров (включая счетчики), например этот код, я использовал useState, useEffect, useContext и нестандартные хуки. Я мог бы получить более подробную информацию о том, как работают хуки в этом ответе, но документация очень хорошо объясняет государственный крюк и другие хуки в деталях, надеюсь, это поможет.
Обновить:Хуки больше не предложение, поскольку версия 16,8 теперь доступна для использования, на сайте React есть раздел, который отвечает на некоторые из часто задаваемые вопросы.
Хорошая аналогия, за исключением того, что в JavaScript технически нет типа данных кортеж.
Ну, деструктурированное присваивание используется как кортеж stackoverflow.com/a/4513061/6335029
Асинхронные хуки? При использовании setSomething, если я затем попробую использовать something сразу после этого, кажется, что у него все еще старое значение ...
Хуки не обновляют его значение после вызова set value до тех пор, пока компонент не будет повторно отрисован. Расширенная библиотека useState от Hookstate (hookstate.js.org) дает вам немедленное обновление значений и множество других функций. Отказ от ответственности: я являюсь автором библиотеки lib.
Не могли бы вы также объяснить, почему мы связываем const с состоянием, которое определенно изменится? const count мне кажется странным
@goonerify кортеж - это конечный упорядоченный список (последовательность) элементов
useState - один из хуков, доступных в React v16.8.0. Это в основном позволяет вам превратить ваши компоненты, не имеющие состояния / функциональные, в компоненты, которые могут иметь собственное состояние.
На самом базовом уровне это используется следующим образом:
const [isLoading, setLoading] = useState(true);
Затем это позволяет вам вызвать setLoading, передав логическое значение.
Это отличный способ иметь функциональный компонент с отслеживанием состояния.
useState () - это пример встроенной ловушки React, которая позволяет вам использовать состояния в ваших функциональных компонентах. Это было невозможно до React 16.7.
Функция useState - это встроенный обработчик, который можно импортировать из пакета реакции. Это позволяет вам добавлять состояние к вашим функциональным компонентам. Используя ловушку useState внутри функционального компонента, вы можете создать часть состояния, не переключаясь на компоненты класса.
useState - это один из встроенных хуков реагирования, доступных в версии 0.16.7.
useState следует использовать только внутри функциональных компонентов. useState - это способ, если нам нужно внутреннее состояние и не нужно реализовывать более сложную логику, такую как методы жизненного цикла.
const [state, setState] = useState(initialState);
Returns a stateful value, and a function to update it.
During the initial render, the returned state (state) is the same as the value passed as the first argument (initialState).
The setState function is used to update the state. It accepts a new state value and enqueues a re-render of the component.
Пожалуйста, обрати внимание, что useState перехватывает обратный вызов для обновления состояния ведет себя иначе, чем компоненты this.setState. Чтобы показать вам разницу, я приготовил два примера.
class UserInfoClass extends React.Component {
state = { firstName: 'John', lastName: 'Doe' };
render() {
return <div>
<p>userInfo: {JSON.stringify(this.state)}</p>
<button onClick = {() => this.setState({
firstName: 'Jason'
})}>Update name to Jason</button>
</div>;
}
}
// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
const [userInfo, setUserInfo] = React.useState({
firstName: 'John', lastName: 'Doe',
});
return (
<div>
<p>userInfo: {JSON.stringify(userInfo)}</p>
<button onClick = {() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
</div>
);
}
ReactDOM.render(
<div>
<UserInfoClass />
<UserInfoFunction />
</div>
, document.querySelector('#app'));<script src = "https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src = "https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id = "app"></div>Новый объект создается при использовании обратного вызова setUserInfo. Обратите внимание, что мы потеряли ключевое значение lastName. Чтобы исправить это, мы могли передать функцию внутри useState.
setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })
См. Пример:
// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
const [userInfo, setUserInfo] = React.useState({
firstName: 'John', lastName: 'Doe',
});
return (
<div>
<p>userInfo: {JSON.stringify(userInfo)}</p>
<button onClick = {() => setUserInfo(prevState => ({
...prevState, firstName: 'Jason' }))}>
Update name to Jason
</button>
</div>
);
}
ReactDOM.render(
<UserInfoFunction />
, document.querySelector('#app'));<script src = "https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src = "https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id = "app"></div>Unlike the setState method found in class components, useState does not automatically merge update objects. You can replicate this behavior by combining the function updater form with object spread syntax:
setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
Для получения дополнительной информации о useState см. официальная документация.
Спасибо за добавление функции в качестве параметра в пример.
ваши сравнительные примеры помогли новичку вроде меня понять использование useState
useState() - это перехватчик React. Хуки позволяют использовать состояние и изменчивость внутри функциональных компонентов.
Хотя вы не можете использовать хуки внутри классов, вы можете обернуть свой компонент класса функцией один и использовать хуки из него. Это отличный инструмент для переноса компонентов из класса в форму функции. Вот полный пример:
В этом примере я буду использовать компонент счетчика. Это оно:
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick = {() => this.inc()}>{this.state.count}</button>
}
}
ReactDOM.render(<Hello count = {0}/>, document.getElementById('root'))<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>Это простой компонент класса с состоянием подсчета, а обновление состояния выполняется методами. Это очень распространенный шаблон в компонентах класса. Во-первых, оберните его функциональным компонентом с тем же именем, который делегирует все свои свойства обернутому компоненту. Также вам нужно отобразить завернутый компонент в возвращении функции. Вот:
function Hello(props) {
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick = {() => this.inc()}>{this.state.count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count = {0}/>, document.getElementById('root'))<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>Это точно такой же компонент, с таким же поведением, тем же именем и одинаковыми свойствами. Теперь давайте перейдем к состоянию подсчета к функциональному компоненту. Вот как это происходит:
function Hello(props) {
const [count, setCount] = React.useState(0);
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { count: props.count };
}
inc() {
this.setState(prev => ({count: prev.count+1}));
}
render() {
return <button onClick = {() => setCount(count+1)}>{count}</button>
}
}
return <Hello {...props}/>
}
ReactDOM.render(<Hello count = {0}/>, document.getElementById('root'))<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity = "sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM = " crossorigin = "anonymous"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity = "sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc = " crossorigin = "anonymous"></script>
<div id='root'></div>Обратите внимание, что метод inc все еще существует, он никому не повредит, на самом деле это мертвый код. Это идея, просто продолжайте поднимать состояние. Когда вы закончите, вы можете удалить компонент класса:
function Hello(props) {
const [count, setCount] = React.useState(0);
return <button onClick = {() => setCount(count+1)}>{count}</button>;
}
ReactDOM.render(<Hello count = {0}/>, document.getElementById('root'))<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity = "sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM = " crossorigin = "anonymous"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity = "sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc = " crossorigin = "anonymous"></script>
<div id='root'></div>Хотя это позволяет использовать хуки внутри компонентов класса, я бы не рекомендовал вам это делать, за исключением случаев, когда вы выполняете миграцию, как я в этом примере. Смешивание компонентов функций и классов приведет к беспорядку в управлении состоянием. надеюсь, это поможет
С уважением
Спасибо loelsonk, я так и сделал
const [dataAction, setDataAction] = useState({name: '', description: ''});
const _handleChangeEventName = (data) => {
if (data.name)
setDataAction( prevState => ({ ...prevState, name : data.name }));
if (data.description)
setDataAction( prevState => ({ ...prevState, description : data.description }));
};
....return (
<input onChange = {(event) => _handleChangeEventName({name: event.target.value})}/>
<input onChange = {(event) => _handleChangeEventName({description: event.target.value})}/>
)useState - это ловушка, которая позволяет добавлять состояние к функциональному компоненту. Он принимает аргумент, который является начальным значением свойства состояния, и возвращает текущее значение свойства состояния и метод, который может обновлять это свойство состояния. Вот простой пример:
import React, { useState } from react
function HookCounter {
const [count, setCount]= useState(0)
return(
<div>
<button onClick{( ) => setCount(count+1)}> count{count}</button>
</div>
)
}
useState принимает начальное значение переменной состояния, которое в данном случае равно нулю, и возвращает пару значений. Текущее значение состояния было вызвано count, а метод, который может обновлять переменную состояния, был вызван как setCount.
По сути, React.useState(0) волшебным образом видит, что он должен вернуть кортеж count и setCount (метод изменения count). Параметр useState устанавливает начальное значение count.
const [count, setCount] = React.useState(0);
const [count2, setCount2] = React.useState(0);
// increments count by 1 when first button clicked
function handleClick(){
setCount(count + 1);
}
// increments count2 by 1 when second button clicked
function handleClick2(){
setCount2(count2 + 1);
}
return (
<div>
<h2>A React counter made with the useState Hook!</h2>
<p>You clicked {count} times</p>
<p>You clicked {count2} times</p>
<button onClick = {handleClick}>
Click me
</button>
<button onClick = {handleClick2}>
Click me2
</button>
);
Основано на примере Энмануэля Дюрана, но показывает два счетчика и записывает лямбда-функции как обычные функции, поэтому некоторым людям это может быть проще.
Приведенные выше ответы хороши, но позвольте мне просто вмешаться, useState является асинхронным, поэтому, если ваше следующее состояние зависит от вашего предыдущего состояния, лучше всего передать useState обратный вызов. См. Пример ниже:
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
// passing a callback to useState to update count
<button onClick = {() => setCount(count => count + 1)}>
Click me
</button>
</div>
);
}
Это рекомендуемый способ, если ваше новое состояние зависит от вычислений из старого состояния.
useState - это ловушка, которая позволяет вам иметь переменные состояния в функциональных компонентах.
В React есть два типа компонентов: класс и функциональные компоненты.
Компоненты класса - это классы ES6, которые происходят от React.Component и могут иметь методы состояния и жизненного цикла:
class Message extends React.Component {
constructor(props) {
super(props);
this.state = {
message: ‘’
};
}
componentDidMount() {
/* ... */
}
render() {
return <div>{this.state.message}</div>;
}
}
Функциональные компоненты - это функции, которые просто принимают аргументы как свойства компонента и возвращают действительный JSX:
function Message(props) {
return <div>{props.message}</div>
}
// Or as an arrow function
const Message = (props) => <div>{props.message}</div>
Как видите, нет методов состояния или жизненного цикла.
React useState - это React Hook, который позволяет вам управлять состоянием в функциональных компонентах.
Например:
import React, { useState } from 'react'
const Example = () => {
// create the "counter" state
const [count, setCount] = useState(0)
return (
<div>
<p>Button clicked {count} times</p>
<button onClick = {() => setCount(count + 1)}>
Count + 1
</button>
</div>
)
}
export default Example
С помощью useState вы можете легко создавать функциональные компоненты с отслеживанием состояния.
Старый эквивалентный способ использования компонентов класса с классом Component и setState:
import React, { Component } from 'react'
class Example extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
render() {
const { count } = this.state
return (
<div>
<p>Button clicked {count} times</p>
<button onClick = {() => this.setState({ count: count + 1 })}>
Count + 1
</button>
</div>
)
}
}
export default Example
Источник:
Ссылки:
Давайте разберемся в useState очень легко и просто
предположим, у нас есть код реакции: -
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Test from './components/Test.jsx'
ReactDOM.render(
<div>
<Test />
</div>
,
document.getElementById('root')
);
Test.jsx
import React from "react";
function Test() {
var x = 5;
function update() {
console.info(x);
return x++;
}
return (
<div>
<h1>{x}</h1>
<button onClick = {update}>click</button>
</div>
);
}
export default Test;
здесь на странице будет отображаться 5, хотя мы вызываем функцию обновления, нажимая кнопку, потому что мы обновляем x, но не между тегами h1, но на самом деле x постоянно меняется всякий раз, когда мы нажимаем на, но он может видеть на консоли
посмотреть результат и проверить консоль, нажав на эту ссылку
здесь usState волшебным образом работает,
Test.jsx с использованием useState
import React, { useState } from "react";
function Test() {
var x = 5;
const [value, setValue] = useState(x);
function update() {
setValue(value + 1);
}
return (
<div>
<h1>{value}</h1>
<button onClick = {update}>click</button>
</div>
);
}
export default Test;
посмотреть результат, нажав на эту ссылку
здесь, при нажатии кнопки значение будет постоянно обновляться, потому что здесь мы используем useState, это функция, которая возвращает 2 вещи: одна - текущее значение состояния, а другая - функция, если мы передадим какое-либо значение этому функция, он обновит текущее состояние vlue, а текущее значение состояния обновит свое value во всех местах, где бы оно ни использовалось, без написания дополнительного кода.
Вы также можете посмотреть исходный код, чтобы понять, как реализован
useState. Вот определение с версии 16.9.