Управление несколькими состояниями внутри хука - PullRequest
1 голос
/ 03 мая 2019

Я недавно начал пытаться изучать хиты React, но я не могу понять некоторые вещи, например, управление несколькими состояниями, я нашел несколько примеров, но ничегокажется, в определенном порядке.Я даже не уверен, как вы должны определять свои состояния, если их больше 2, и вы хотите изменить их индивидуально, если это будет выглядеть так:

const [slides, setSlides] = useState([])
const [currentSlide, setCurrentSlide] = useState(0)
const [tagName, setTagName] = useState([])

Или вот так:

const [states, setStates] = useState({
  slides: [],
  currentSlide: 0,
  tagName: []
})

И если оба варианта или второй является жизнеспособным (честно говоря, я бы предпочел второй вариант, так как он менее повторяется при вызове useState и ближе к стандартной метате состояния), как можно было бы изменить состояния в таком примере?Я ничего не мог найти по этому поводу, так что я попробовал вот что:

useEffect(() => {
  Object.entries(Slides).forEach(slide => {
   setStates(prevState => ({ slides: [...prevState.slides, slide[1]] }))
  })

}, [])

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

Есть идеи, что я делаю не так?И на каком из этих методов передовой практики?

Спасибо!

Ответы [ 2 ]

1 голос
/ 03 мая 2019

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

Я бы порекомендовал прочитать эту статью о useState против useReducer.

1 голос
/ 03 мая 2019

С точки зрения обновления состояния, первый шаблон намного проще и проще, потому что каждая функция stateUpdate будет отвечать за обновление одного значения, которое может быть obj/array/int/bool/string.Другое дело, что для доступа к каждому значению состояния (это будет объект) вам нужно написать states.slides, states.tagName и т. Д.

В первом случае обновление состояния будет простым:

// only value in case of int/string/bool
updateState({ [key]: value }) or updateState(value);

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

updateState({
  ...obj,
  [key]: newValue
})

Чтобы обновить массив слайдов:

updateState(prevState => ({
  ...prevState,
  slides: newArray
}))

Обработка обновления сложного состояния:

Использование useReducer для обработки сложного обновления состояния, напишите отдельную функцию редуктора с типами действий и для каждого типа действия, чтобы вычислить и вернуть новое состояние.

Например:

const initialState = { slides: [], tagName: [], currentSlide: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'SLIDES':
      return { ... };
    case 'TAGNAME':
      return { ... };
    case 'CURRENT_SLIDE':
      return { ... }
    default:
      throw new Error();
  }
}

function Counter({initialState}) {
  const [state, dispatch] = useReducer(reducer, initialState);
  ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...