react 中使用九宫格抽奖

react 中使用九宫格抽奖

说明:因为大多数使用到的基本都是活动相关的,九宫格的对应的每个奖励也都是有中奖率的,具体的奖励都是后端返回的,所以我们在点击抽奖时一定会请求后端接口获取到返回的数据

1.首先,看jsx部分

return (
	<ul styleName="list"> //这里我是用一个list去动态渲染他的奖励数据,当然,它的第五项是空的
	  {list.map((item, index) => {
	    if (index === 4) { //所以这边到了第五项的时候我只是把它的立即抽奖的图片放入了,然后加上了一个点击事件
	      return (
	        <li key={index}>
	          <img src={item.pic} alt="" onClick={handleClick} />
	        </li>
	      );
	    }
	    return ( //其他的则正常渲染
	      <li key={index}>
	        <img src={item.pic} alt="" />
	        {item.active ? <img src="" alt="" styleName="active" /> : null}
	      </li>
	    );
	  })}
	</ul>
)

2.再看函数体部分

const initialActiveIndexRef = useRef(0);//这边是一个初始化
const resultRef = useRef({
  result: null,
  resultIndex: -1,
  pending: false,
  rolling: false,
  error: null,
});

const INTERVAL = 125;//转盘的速度
const handleClick = useCallback(async () => {
    const newInitialize = JSON.parse(JSON.stringify(Initialize));//不直接修改state,我这边是转化了一下
    if (resultRef.current.rolling || resultRef.current.pending) {
      return;
    }//如果转盘在转或者按钮锁,则无法点击
    if (newInitialize.value == 0) {
      toast.show('您的抽奖次数不足');
      return;
    }//次数不足的话,直接不请求后端,前端拦截,减少请求
    resultRef.current.pending = true;//开始后,把按钮锁和转盘锁打开
    resultRef.current.rolling = true;
    try {
      const res = await hello(); //这里是await 请求结果
      if (res.code == -1) { //如果请求出错的话,直接抛出了一个错误的小弹框
      	toast.show('错误');
        resultRef.current.result = null; //并且把中奖数据设置为空,按钮锁设置为false,转盘设置为false
        resultRef.current.pending = false;
        resultRef.current.rolling = false;
        return;
      }
      const resId = res.gift_id; //得到一个奖励的id
      const resIndex = list.findIndex(i => i.gift_id == resId); //再用奖励id去找list内是否存在对应的奖励
      if (resIndex < 0) { //如果不存在,则抛出错误的弹框
        toast.show('未知错误');
        resultRef.current.result = null;
        resultRef.current.pending = false;
        resultRef.current.rolling = false;
        return;
      } //否则,继续往下走
      resultRef.current.result = res;//设置奖励信息
      resultRef.current.resultIndex = resIndex; //设置对应的奖励下标
      newInitialize.value -= 1;//再减去一次抽奖次数
      setInitialize({
        ...newInitialize, //重新设置
      });
    } catch (err) {//如果请求出错,则catch出去
      toast.show('数据请求出错,请重试');
      resultRef.current.pending = false;
      resultRef.current.rolling = false;
      resultRef.current = null;
      return;
    }//否则,继续往下走
    let currentIndex = initialActiveIndexRef.current;//设置一个默认的值
    setList(
      list.map((i, index) => {
        return {
          ...i,
          active: index === currentIndex,
        };
      }),
    );
    let loop = -1; //初始化
    const timer = setInterval(() => { //开始转动
      loop = currentIndex === initialActiveIndexRef.current ? loop + 1 : loop;//loop + num 与 转动的圈数有关
      if (currentIndex < 2) {
        currentIndex += 1;
      } else if (currentIndex === 2 || currentIndex === 5) {
        currentIndex += 3;
      } else if (currentIndex === 3 || currentIndex === 6) {
        currentIndex -= 3;
      } else if (currentIndex > 6) {
        currentIndex -= 1;
      }
      setList( //设置转动高亮状态
        list.map((i, index) => {
          return {
            ...i,
            active: index === currentIndex,
          };
        }),
      );

      if (loop > 0) {
        if (!resultRef.current.result || resultRef.current.resultIndex < 0) {//这边也是做的一个错误拦截
          clearInterval(timer);
          resultRef.current.rolling = false;
          return;
        }
        if (currentIndex !== resultRef.current.resultIndex) {
          return;
        }
        resultRef.current.rolling = false; //清楚转盘
        clearInterval(timer);//清除延时器
        initialActiveIndexRef.current = currentIndex;//转动完成后设置值
      }
    }, INTERVAL);//每一个格子停留的时间在外定义了
    const timerOut = setTimeout(() => {
      setIsShow(true);//我这边是写了一个小弹框展示
      resultRef.current.pending = false;//这边我是让它在我弹框展示奖励后再取消按钮锁,否则,在等弹框展示奖励过程中再次抽奖,算是bug了
      clearTimeout(timerOut);
    }, 2200);
  }, [list, Initialize]);//需要依赖一下抽奖的次数,和list

整个组件是一个函数式组件,所以有些地方之前用class组件的小伙伴如果不理解的话,可以看一下react官方文档的hooks部分哦

由于没有效果图,所以可能会有些奇奇怪怪,望大佬们见谅哈
本文章出自新手,轻喷
附上react官方链接,点击即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React九宫格抽奖是一种通过使用React框架来实现的抽奖游戏。在这个游戏,用户点击抽奖按钮后,九宫格开始旋转,并最终停在一个奖项上。 在实现这个功能的过程,可以使用以下方法: 1. 首先,在点击抽奖按钮时,执行handleClick方法。这个方法会调用start方法来开始九宫格的旋转,并发起一个请求来获取奖项。 2. 在start方法,首先设置九宫格的起始位置,结果序号和旋转速度。然后,使用定时器来控制九宫格的旋转。在每次定时器触发时,判断是否达到了预定的结果序号。如果没有达到,则继续旋转,并更新九宫格的活动位置。 3. 在每次旋转时,根据活动位置的变化,更新九宫格奖项的激活状态,并将更新后的状态应用到界面上。 4. 当九宫格达到了预定的结果序号时,停止旋转,并展示奖弹窗。 5. 可以使用setTimeout来延迟展示奖弹窗的时间,并在展示完成后清除定时器。 通过以上步骤,就可以实现React九宫格抽奖游戏。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [react实现九宫格抽奖 - h5](https://blog.csdn.net/qq_16726735/article/details/121405662)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [React九宫格抽奖](https://blog.csdn.net/aoba8934/article/details/102322360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值