Существует ли общий способ установки состояния в крючках реакции? Как управлять несколькими состояниями?

#reactjs #react-native #react-hooks

#язык JavaScript #реагирует на #реагируют-крючки

Вопрос:

У меня есть вопрос, могу ли я использовать useState generic в крючках React, точно так же, как я могу это сделать в компонентах React, управляя несколькими состояниями?

 state = { input1: "", input2: "", input3: "" // .. more states};handleChange = (event) =gt; { const { name, value } = event.target; this.setState({ [name]: value, });}; 

Комментарии:

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

2. @ravibagul91 не обязательно, вы можете управлять сложным состоянием с помощью useState

3. @Джеймс Да, это то, что я ищу. Я углублюсь в ваш связанный ответ

Ответ №1:

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

  1. Управляйте одним объектом с несколькими состояниями (обратите внимание, что массив является объектом).
  2. Используйте useReducer if ( 1 ) слишком сложно.
  3. Используйте несколько useState для каждой пары ключ-значение (учитывайте удобочитаемость и ее обслуживание).

Проверьте это:

 // Ids-values pairs.const complexStateInitial = { input1: "", input2: "", input3: "" // .. more states};function reducer(state, action) { return { ...state, [action.type]: action.value };}export default function App() { const [fromUseState, setState] = useState(complexStateInitial); // handle generic state from useState const onChangeUseState = (e) =gt; { const { name, value } = e.target; setState((prevState) =gt; ({ ...prevState, [name]: value })); }; const [fromReducer, dispatch] = useReducer(reducer, complexStateInitial); // handle generic state from useReducer const onChangeUseReducer = (e) =gt; { const { name, value } = e.target; dispatch({ type: name, value }); };  return ( lt;gt; lt;h3gt;useStatelt;/h3gt; lt;divgt; {Object.entries(fromUseState).map(([key, value]) =gt; ( lt;input key={key} name={key} value={value} onChange={onChangeUseState} /gt; ))} lt;pregt;{JSON.stringify(fromUseState, null, 2)}lt;/pregt; lt;/divgt; lt;h3gt;useReducerlt;/h3gt; lt;divgt; {Object.entries(fromReducer).map(([key, value]) =gt; ( lt;input name={key} key={key} value={value} onChange={onChangeUseReducer} /gt; ))} lt;pregt;{JSON.stringify(fromReducer, null, 2)}lt;/pregt; lt;/divgt; lt;/gt; );} 

Редактировать Обрабатывать Несколько Состояний

Примечания

  • В отличие от setState метода, найденного в компонентах класса, useState не выполняет автоматическое объединение объектов обновления. Вы можете повторить это поведение, объединив форму средства обновления функций с синтаксисом распространения объектов:
 setState(prevState =gt; { // Object.assign would also work return {...prevState, ...updatedValues};}); 

Обратитесь к документам React.

Комментарии:

1. При этом не используются крючки react.

2. Это правильно, но не так, как это можно сделать с помощью крючков реакции.

3. setState происходит от useState : const [state, setState] = useState(initialState);

4. @DennisVash: Я приношу свои извинения. Вы правы. Я не видел вашего объявления setState и предположил, что это тот же метод setState класса, о котором, похоже, спрашивал OP. Путаница для меня заключалась в том, что вы использовали одно и то же название метода.

5. @Джеймс: Не пытаюсь быть самонадеянным. Я думаю, мы действительно согласны. Ваш пользовательский ответ на крючок, в конечном счете, вероятно, будет тем ответом, который ищет ОП.

Ответ №2:

Правильный способ сделать то, что вы пытаетесь сделать, — это создать свой собственный крючок, который используется useState внутри.

Вот пример:

 // This is your generic reusable hook.const useHandleChange = (initial) =gt; { const [value, setValue] = React.useState(initial); const handleChange = React.useCallback( (event) =gt; setValue(event.target.value), // This is the meaty part. [] ); return [value, handleChange];}const App = () =gt; { // Here we use the hook 3 times to show it's reusable. const [value1, handle1] = useHandleChange('one'); const [value2, handle2] = useHandleChange('two'); const [value3, handle3] = useHandleChange('three'); return lt;divgt; lt;divgt; lt;input onChange={handle1} value={value1} /gt; lt;input onChange={handle2} value={value2} /gt; lt;input onChange={handle3} value={value3} /gt; lt;/divgt; lt;h2gt;States:lt;/h2gt; lt;ulgt; lt;ligt;{value1}lt;/ligt; lt;ligt;{value2}lt;/ligt; lt;ligt;{value3}lt;/ligt; lt;/ulgt; lt;/divgt;}ReactDOM.render(lt;App /gt;, document.querySelector("#app")) 
 lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"gt;lt;/scriptgt;lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"gt;lt;/scriptgt;lt;div id="app"gt;lt;/divgt; 

Обратите внимание на использование React.useCallback, чтобы ваш хук не возвращал новую функцию обработчика при каждом рендеринге. (Нам не нужно указывать setValue в качестве зависимости, потому что React гарантирует, что она никогда не изменится)

Ответ №3:

На самом деле я это не проверял, но это должно сработать.

Видишь https://reactjs.org/docs/hooks-reference.html#usestate для получения дополнительной информации.

 import React, {useState} from 'react';const MyComponent = () =gt; { const [name, setName] = useState('Default value for name'); return (lt;divgt;lt;button onClick={()=gt;setName('John Doe')}}gt;Set Namelt;/buttongt;lt;/divgt;);};export default MyComponent; 

Комментарии:

1. Я не понимаю, как это отвечает на вопрос? Вы только что привели пример того , как использовать setState , как ОП выводит из этого, как установить его динамически?