【问题标题】:Correct way to update a state inside useReducer (React.js)在 useReducer (React.js) 中更新状态的正确方法
【发布时间】:2022-01-10 15:01:32
【问题描述】:

我有两个“选择”输入 (html) 用于显示信息,这是状态:

const [foodValues, setFoodValues] = useState({ type: 'Everything', category: 'Everything' })

一切正常,我在两个输入上都使用了经典的 handleChange():

const handleChange = e => {
    const value = e.target.value 
    const name = e.target.name
    dispatch({type: ACTIONS.CHANGE, payload: {e: value, name: name}})
}

如你所见,我调用dispatch来使用useReducer:

const OperationsReducer = (foodReducer, action) => {
  const { foodValues, setFoodValues } = useContext(AllContext)

  switch (action.type) {
    case ACTIONS.CHANGE:
      setFoodValues({
        ...foodValues,
        [action.payload.name]: action.payload.e
     })
   break;
  }
}

而且效果很好!但是我在控制台中收到了这个警告:

警告不要在 useEffect(...)、useMemo(...) 或其他内置 Hooks 中调用 Hooks。你只能在 React 函数的顶层调用 Hooks。有关详细信息,请参阅

所以,我的问题是:有没有办法在没有警告的情况下使用这个 useReducer? 我知道我可以在它之外使用 setFoodValues,但我很好奇(我真的很喜欢使用 useReducer...)。我已经阅读了关于这个主题的 React 文档,但我看到有些人在做一些非常奇怪(而且很酷)的东西来解决这个问题。

【问题讨论】:

  • 如果你创建自己的钩子,它必须被称为“使用....”,在你的例子中 useOperationsReducer,但我认为你的逻辑有一些完全错误,以及你如何正在使用它。

标签: reactjs use-state use-reducer


【解决方案1】:
const initialState = { type: 'Everything', category: 'Everything' };

function reducer(state, action) {
  switch (action.type) {
    case ACTIONS.CHANGE:
      return {
        ...state,
        [action.payload.name]: action.payload.e
      };
    default:
      return state;
  }
}

function Component() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const handleChange = e => {
    const value = e.target.value
    const name = e.target.name
    dispatch({type: ACTIONS.CHANGE, payload: {e: value, name: name}})
  }
  
  ...
}

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 2020-08-15
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2021-01-17
    相关资源
    最近更新 更多