在 React 组件中结合 useState 钩子

combining useState hook in a react component

我最近开始大量使用 React Hooks。

使用 "React.useState" 时状态管理对我来说似乎更直观。

无论如何,虽然它工作正常,但我知道当我开始保存到 state 的值越多,它就会开始变得混乱。

例如,随着我的汽车零件应用程序的发展,它现在看起来像这样:

const [isShown, setIsShown] = React.useState(false);
const [idVal, setIdValue] = React.useState(false);
const [partNameVal, setPartNameValue] = React.useState(false);
const [engineEngineEngineTypeVal, setEngineEngineTypeValue] = React.useState(false);
const [displacementVal, setDisplacementValue] = React.useState(false);
const [makeVal, setMakeValue] = React.useState(false);
const [countryVal, setCountryValue] = React.useState(false);

const hide = () => setIsShown(false);

const show = (id, partName, engineEngineType, displacement, department, country) => {
    setIsShown(true);
    setIdValue(id);
    setPartNameValue(partName);
    setEngineTypeValue(engineEngineType);
    setDisplacementValue(displacement);
    setMakeValue(department);
    setCountryValue(country);
}

<p>ID:  {idVal}</p>
<p>PartName:  {partNameVal}</p>
<p>EngineType:  {engineEngineTypeVal}</p>
<p>Displacement:  {displacementVal}</p>
<p>Make:  {makeVal}</p>
<p>Country:  {countryVal}</p>

我想知道是否有办法让它更具可读性,但仍然非常直观。

谢谢!

通常您想要处理单个对象或使用 useReducer,例如:

const INITIAL_CAR = {
  id: 0,
  part: "4xE3",
  country: "USA",
  // ... More entries
};

const CarApp = () => {
  const [car, setCar] = useState(INITIAL_CAR);
  const [isShown, setIsShown] = useState(false);

  const show = (carProps) => {
    setIsShown(true);
    setCar(carProps);
  };

  const { id, part, engine, displacement, make, county } = car;

  const updateCountry = (country) =>
    setCar((prevCar) => ({ ...prevCar, country }));

  const updateCarProperty = ({ property, value }) =>
    setCar((prevCar) => ({ ...prevCar, [property]: value }));

  return (
    <div>
      {isShown && (
        <>
          <p>ID: {id}</p>
          <p>PartName: {part}</p>
          <p>EngineType: {engine}</p>
          <p>Displacement: {displacement}</p>
          <p>Make: {make}</p>
          <p>Country: {country}</p>{" "}
        </>
      )}
      // use show, updateCountry, updateProperty etc.
    </div>
  );
};

我会说 useReducer 钩子就是这种情况。

https://reactjs.org/docs/hooks-reference.html#usereducer

const initialState = {
      isShown: false,
      idVal: 0,
      ....
};

function reducer(state, action) {
  switch (action.type) {
    case 'show':
      return {
        ...state,
        isShown: true,
        idVal: action.payload.idVal
      };
    case 'hide':
      return {
        ...state,
        isShown: false
      }
    ...
    default:
      throw new Error();
  }
}

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

dispatch({type: 'show', payload: { idVal: 1}})

您可以创建一个新文件以从组件中提取所有挂钩逻辑。

调用,例如 useHooks.js

export default () => {
const [isShown, setIsShown] = React.useState(false);
const [idVal, setIdValue] = React.useState(false);
const [partNameVal, setPartNameValue] = React.useState(false);
const [engineEngineEngineTypeVal, setEngineEngineTypeValue] = React.useState(false);
const [displacementVal, setDisplacementValue] = React.useState(false);
const [makeVal, setMakeValue] = React.useState(false);
const [countryVal, setCountryValue] = React.useState(false);

const hide = () => setIsShown(false);

const show = (id, partName, engineEngineType, displacement, department, country) => {
    setIsShown(true);
    setIdValue(id);
    setPartNameValue(partName);
    setEngineTypeValue(engineEngineType);
    setDisplacementValue(displacement);
    setMakeValue(department);
    setCountryValue(country);
}

return [isShown, idVal, partNameVal, engineEngineEngineTypeVal, displacementVal, 
makeVal, countryVal, show, hide];
}

这里的想法是将所有挂钩逻辑放在一个函数中,return JSX 中需要的值。

并在您的组件中导入并使用从 useHooks 导出的所有属性

import useHooks from './useHooks';

const [isShown, idVal, partNameVal, engineEngineEngineTypeVal, displacementVal, 
makeVal, countryVal, show, hide] = useHooks();

希望思路清晰

我在一个组件中处理这么多状态的主要方式是使用一个 useState,这样它就只是一个大对象。

这是一个小例子:

const [state, setState] = useState({
  num: 1,
  cars: ['volvo', 'mazda'],
  john: {name: 'John', last: 'Foo'}
})

如果你想改变一些东西,我通常使用这个功能

const onChange = (name, value) => {
  setState(prevState => ({...prevState, [name]: value}))
}

这会将键 name 更改为值 value。这在我眼里更清晰了。