当初始值改变时,useReducer 的状态 return 不会改变

state return by useReducer doesn't change when init value change

dishState return by useReducer 即使 initDishState 改变了也没有改变。是不是异步进程导致变量在某处发生变异?

export default function DishModal({
  type,
  itemCode,
  modalRef,
  initDishState,
  addedOrderState,
}: DishModalType): JSX.Element {
  const { menuInfo } = useContext(MenuContext);
  const menuDetailData = menuInfo.menu_detail;
  const itemInfo = menuDetailData[itemCode];
  const [dishState, DishDispatch] = useReducer(dishReducer, initDishState);
  console.log("initDishState", initDishState);
  console.log("dishState", dishState);

我调用DishModal时的代码是

export default function Cart({ cartState }: CartType): JSX.Element {
  const { menuInfo } = useContext(MenuContext);
  const menuDetail: IPayload = menuInfo.menu_detail;
  const ListOfDish = Object.entries(cartState).map(
    ([dishKey, dishValue], orderIdx) => {
      const dishState: IPayload[] = dishValue.state;
      const dishInit: IPayload = dishValue.init;
      const [, itemCode] = JSON.parse(dishKey);
      const dishInfo = menuDetail[itemCode];
      if (!dishInfo) return null; // avoid invalid data caused by backend
      return (
        <Dish
          key={orderIdx}
          dishKey={dishKey}
          dishInfo={dishInfo}
          dishState={dishState}
          dishInit={dishInit}
        />
      );
    }
  );
  return (
    <div id="cart">
      <div className="clearfix">
        <Link to="/" type="button" className="btn-close"></Link>
      </div>
      <h1>Cart</h1>
      {ListOfDish}
    </div>
  );
}

function Dish({ dishKey, dishInfo, dishState, dishInit }: DishType) {
  const { menuInfo } = useContext(MenuContext);
  const cartDispatch = useContext(CartDispatchContext);
  const modalRef = useRef<HTMLDivElement>(null);
  const menuDetailData: IPayload = menuInfo.menu_detail;
  const dishQuantity = dishState.length;
  const compactState = summarizeDishState(dishState);

  const handleModal = () => {
    if (modalRef.current) {
      const modalController = Modal.getOrCreateInstance(modalRef.current);
      modalController.show();
    }
  };

  const ListOfSelectedOption = Object.entries(compactState).map(
    ([optionCode, optionQuantity]) => {
      const optionInfo = menuDetailData[optionCode];
      const optionName = attrLang(optionInfo, "lang");
      return <li key={optionCode}>{`${optionName} (${optionQuantity})`}</li>;
    }
  );

  return (
    <div className="card mb-3">
      <div className="row">
        <div className="col">
          <img
            src={imgFullPath(dishInfo.img)}
            className="img-fluid rounded-start"
            alt="..."
          ></img>
        </div>
        <div className="col d-flex flex-column">
          <div className="card-body">
            <h5>{attrLang(dishInfo, "lang")}</h5>
            <ul>{ListOfSelectedOption}</ul>
          </div>
          <div className="card-footer dish-price">
            <strong>{dishInfo.price}</strong>円(税込み
            <strong>{Math.round(dishInfo.price * 1.1) || undefined}</strong>円)
          </div>
        </div>
        <div className="col-2">
          <button className="btn btn-primary" onClick={handleModal}>
            edit
          </button>
          <DishQuantitySelector
            dishKey={dishKey}
            addedState={dishInit}
            quantity={dishQuantity}
            dispatch={cartDispatch}
          />
        </div>
      </div>
      <DishModal
        type={"replace"}
        itemCode={dishInfo.poscd}
        modalRef={modalRef}
        initDishState={dishState}
        addedOrderState={dishInit}
      />
    </div>
  );
}

reducer 的当前值不应在初始值更改时更改。这就是为什么它被称为 初始值

useReducer returns 调度程序(我在这里重命名是因为约定为构造函数(和 React 中的组件)保留以大写字母开头的变量)。

const [dishState, dishDispatch] = useReducer(dishReducer, initDishState);

要更改 reducer 中的值,您需要分派一个操作:

dishDispatch({type: 'change', payload: 'foo'});

如果你想使用 props 的值,那么你可能应该直接使用 props,而不是使用 reducer。