ReactJS-派遣REDUX动作时无限循环

发布于 2025-02-12 08:34:01 字数 4151 浏览 1 评论 0原文

几个小时我遇到了一些问题,我真的不知道为什么当我派遣Redux Action时使用效果给我无限的循环?因为我希望我的页面是从顺序状态更改值后会刷新的。是否不允许将异步状态从redux置于使用效果?抱歉,我仍然是新手..

orderslice.js

export const orderPay = createAsyncThunk(
  'order/orderPay',
  async (order, thunkAPI) => {
    try {
      const user1 = thunkAPI.getState().user.userInfo;
      const config = {
        headers: {
          'Content-Type': 'Application/json',
          Authorization: `Bearer ${user1.token}`,
        },
      };

      const res = await axios.put(
        `http://localhost:8000/api/order/${order.orderId}/pay`,
        order.paymentResult,
        config
      );
      const data = await res.data;
      return data;
    } catch (error) {
      thunkAPI.rejectWithValue(
        error.response && error.response.data.message
          ? error.response.data.message
          : error.response
      );
    }
  }
);

const orderSlice = createSlice({
  name: 'order',
  initialState: {
    loading: false,
    error: '',
    order: {},
    success: false,
  },
  reducers: {
    orderDetail: (state, action) => {
      state.order = action.payload;
    },
    orderPayReset: (state, action) => {
      state.loading = false;
      state.error = '';
      state.order = {};
      state.success = false;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(postOrder.pending, (state, action) => {
        state.loading = true;
        state.order = {};
        state.success = false;
      })
      .addCase(postOrder.fulfilled, (state, action) => {
        state.loading = false;
        state.order = action.payload;
        state.success = true;
      })
      .addCase(postOrder.rejected, (state, action) => {
        state.error = action.payload;
      })
      .addCase(orderDetail.pending, (state, action) => {
        state.loading = true;
        state.order = {};
        state.success = false;
      })
      .addCase(orderDetail.fulfilled, (state, action) => {
        state.loading = false;
        state.order = action.payload;
        state.success = true;
      })
      .addCase(orderDetail.rejected, (state, action) => {
        state.error = action.payload;
      })
      .addCase(orderPay.pending, (state, action) => {
        state.loading = true;
        state.success = false;
      })
      .addCase(orderPay.fulfilled, (state, action) => {
        state.loading = false;
        state.success = true;
      })
      .addCase(orderPay.rejected, (state, action) => {
        state.error = action.payload;
      });
  },
});

orderscreen.jsx

const OrderScreen = () => {
  const navigate = useNavigate();
  const { orderId } = useParams();

  const [sdkReady, setSdkReady] = useState(false);

  const { paymentMethod } = useSelector((state) => state.cart);
  const { userInfo } = useSelector((state) => state.user);
  const { success, loading, error, order, orderPaid } = useSelector(
    (state) => state.order
  );

  const dispatch = useDispatch();

  useEffect(() => {
    const addPaypalScript = async () => {
      const res = await axios.get(`http://localhost:8000/api/config/paypal`);
      const data = await res.data;
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = `https://www.paypal.com/sdk/js?client-id=${data}`;
      script.async = true;
      script.onload = () => {
        setSdkReady(true);
      };
      document.body.appendChild(script);
      return data;
    };
    (async () => await addPaypalScript())();

    if (!order || success) {
      dispatch(orderPayReset());
      dispatch(orderDetail(orderId));
    } else if (!order.isPaid) {
      if (!window.paypal) {
        addPaypalScript();
      } else {
        setSdkReady(true);
      }
    }
  }, [orderId, dispatch]);

  const successPaymentHandler = (paymentResult) => {
    dispatch(orderPay({ orderId, paymentResult }));
    order.isPaid = true;
  };

  // console.log(orderPaid);

  return loading ? (
      <h1>Order {order._id}</h1>
)

i got some problem for a couple hours, i really dont know why useeffect give me infinite loop when i dispatch the redux action ? because i want my page is will refresh after i change the value from order state. is there not allowed to put the async state from redux in useeffect? sorry im still new..

orderSlice.js

export const orderPay = createAsyncThunk(
  'order/orderPay',
  async (order, thunkAPI) => {
    try {
      const user1 = thunkAPI.getState().user.userInfo;
      const config = {
        headers: {
          'Content-Type': 'Application/json',
          Authorization: `Bearer ${user1.token}`,
        },
      };

      const res = await axios.put(
        `http://localhost:8000/api/order/${order.orderId}/pay`,
        order.paymentResult,
        config
      );
      const data = await res.data;
      return data;
    } catch (error) {
      thunkAPI.rejectWithValue(
        error.response && error.response.data.message
          ? error.response.data.message
          : error.response
      );
    }
  }
);

const orderSlice = createSlice({
  name: 'order',
  initialState: {
    loading: false,
    error: '',
    order: {},
    success: false,
  },
  reducers: {
    orderDetail: (state, action) => {
      state.order = action.payload;
    },
    orderPayReset: (state, action) => {
      state.loading = false;
      state.error = '';
      state.order = {};
      state.success = false;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(postOrder.pending, (state, action) => {
        state.loading = true;
        state.order = {};
        state.success = false;
      })
      .addCase(postOrder.fulfilled, (state, action) => {
        state.loading = false;
        state.order = action.payload;
        state.success = true;
      })
      .addCase(postOrder.rejected, (state, action) => {
        state.error = action.payload;
      })
      .addCase(orderDetail.pending, (state, action) => {
        state.loading = true;
        state.order = {};
        state.success = false;
      })
      .addCase(orderDetail.fulfilled, (state, action) => {
        state.loading = false;
        state.order = action.payload;
        state.success = true;
      })
      .addCase(orderDetail.rejected, (state, action) => {
        state.error = action.payload;
      })
      .addCase(orderPay.pending, (state, action) => {
        state.loading = true;
        state.success = false;
      })
      .addCase(orderPay.fulfilled, (state, action) => {
        state.loading = false;
        state.success = true;
      })
      .addCase(orderPay.rejected, (state, action) => {
        state.error = action.payload;
      });
  },
});

OrderScreen.jsx

const OrderScreen = () => {
  const navigate = useNavigate();
  const { orderId } = useParams();

  const [sdkReady, setSdkReady] = useState(false);

  const { paymentMethod } = useSelector((state) => state.cart);
  const { userInfo } = useSelector((state) => state.user);
  const { success, loading, error, order, orderPaid } = useSelector(
    (state) => state.order
  );

  const dispatch = useDispatch();

  useEffect(() => {
    const addPaypalScript = async () => {
      const res = await axios.get(`http://localhost:8000/api/config/paypal`);
      const data = await res.data;
      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = `https://www.paypal.com/sdk/js?client-id=${data}`;
      script.async = true;
      script.onload = () => {
        setSdkReady(true);
      };
      document.body.appendChild(script);
      return data;
    };
    (async () => await addPaypalScript())();

    if (!order || success) {
      dispatch(orderPayReset());
      dispatch(orderDetail(orderId));
    } else if (!order.isPaid) {
      if (!window.paypal) {
        addPaypalScript();
      } else {
        setSdkReady(true);
      }
    }
  }, [orderId, dispatch]);

  const successPaymentHandler = (paymentResult) => {
    dispatch(orderPay({ orderId, paymentResult }));
    order.isPaid = true;
  };

  // console.log(orderPaid);

  return loading ? (
      <h1>Order {order._id}</h1>
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文