在 hook 中管理多个状态

Managing multiple states inside hook

我最近开始尝试学习React hooks,但对于我的生活我无法弄清楚一些事情,比如多状态管理,我已经找到了一些例子,但似乎没有什么特定的模式。我什至不确定如果有超过 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]] }))
  })

}, [])

我为了得到一些不错的结果而弄乱了它,但我无法让它正常工作。

对我做错了什么有什么想法吗?其中哪一个是最佳实践方法?

谢谢!

在更新状态方面,第一个模板非常容易和简单,因为每个stateUpdate 函数将负责更新单个值,可以是obj/array/int/bool/string。另一件事是,要访问状态的每个值(它将是一个对象),您需要编写 states.slidesstates.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处理复杂的状态更新,编写一个单独的具有动作类型的reducer函数,并为每个动作类型计算和return新状态。

例如:

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);
  ....
}

确实,useState 挂钩在处理复杂状态对象时会变得非常冗长。 这种情况下,也可以考虑使用useReducer钩子

我建议阅读 this article 关于 useStateuseReducer 的内容。