lucky-canvas icon indicating copy to clipboard operation
lucky-canvas copied to clipboard

初始化的start函数中如果用到了state值,抽奖时state值不能及时更新

Open ZhanghaoH opened this issue 2 years ago • 8 comments

  • 你当前是什么框架(必填):react
  • 你使用的是哪个包(必填):@lucky-canvas/react
  • 你当前插件的版本(必填):^0.1.10
  • 当前环境是小程序还是浏览器(选填):

screenshot-20220613-141653

  • 详细描述你的bug:
  • 问题代码(重要):代码是从官方react示例里改了一下在线运行的
// 代码开始, 别再放歪了行吗
import React, { useState, useRef, useEffect } from 'react'
import { LuckyWheel } from '@lucky-canvas/react'

export default function App() {
  const [blocks] = useState([
    { padding: '10px', background: '#869cfa' }
  ])
  const [flagText, setFlag] = useState('kaishi')
  const [prizes] = useState([
    { background: '#e9e8fe', fonts: [{ text: '0' }] },
    { background: '#b8c5f2', fonts: [{ text: '1' }] },
    { background: '#e9e8fe', fonts: [{ text: '2' }] },
    { background: '#b8c5f2', fonts: [{ text: '3' }] },
    { background: '#e9e8fe', fonts: [{ text: '4' }] },
    { background: '#b8c5f2', fonts: [{ text: '5' }] },
  ])
  const [buttons] = useState([
    { radius: '40%', background: '#617df2' },
    { radius: '35%', background: '#afc8ff' },
    {
      radius: '30%', background: '#869cfa',
      pointer: true,
      fonts: [{ text: '开始', top: '-10px' }]
    }
  ])
  const start = () => { // 点击抽奖按钮会触发star回调
        myLucky.current.play()
        setTimeout(() => {
          const index = Math.random() * 6 >> 0
          myLucky.current.stop(index)
        }, 2500)
      }
  const end = (prize) => { alert('恭喜你抽到 ' + prize.fonts[0].text+ flagText + ' 号奖品')}
  useEffect(() => {
    setTimeout(() => {
      setFlag('kaishile')
    }, 5000)
  }, [])
  useEffect(() => {
    console.log(flagText)
  }, [flagText])
  const myLucky = useRef()
  return <div>
    <LuckyWheel
      ref={myLucky}
      width="300px"
      height="300px"
      blocks={blocks}
      prizes={prizes}
      buttons={buttons}
      onStart={start}
      onEnd={prize => { // 抽奖结束会触发end回调
         end(prize)
      }}
    />
  </div>
}
// 代码结束

ZhanghaoH avatar Jun 13 '22 06:06 ZhanghaoH

我这边真实场景是 页面进入后 初始化奖品列表,拿到一个服务端返回的id,然后供start抽奖时传给服务端,现在发现每次调用start似乎调用的一直是页面初始化时绑定的start函数,我这边可以用useRef解决,但更想确认一下,是否是现状,还是我哪里使用不正确

ZhanghaoH avatar Jun 13 '22 06:06 ZhanghaoH

这个确实是现状, 解决方案是使用 key 或 useRef , 我不知道是不是我封装的有问题, 为了兼容 react@15 我使用的是 class 组件

buuing avatar Jun 13 '22 17:06 buuing

嗯 我有空试试看,6月活动多 好忙,有空我也看看研究下;另外有点尴尬,你说的key是什么意思

ZhanghaoH avatar Jun 14 '22 02:06 ZhanghaoH

有人这样给组件加一个key, 每次key发生变化时, 让当前组件重新渲染, 这样这里面的数据就是最新的, 还不如 useRef 合理

<LuckyWheel
  ...
  key={number}
  ...
/>

buuing avatar Jun 14 '22 02:06 buuing

我大概看了下,react包里的componentDidUpdate,props变化时监听的属性不太够,没有去做start end的变化判断,只有基本配置变得时候会更新

ZhanghaoH avatar Jun 14 '22 02:06 ZhanghaoH

我大概看了下,react包里的componentDidUpdate,props变化时监听的属性不太够,没有去做start end的变化判断,只有基本配置变得时候会更新

不知道跟这个有没有关系,;看到这个key,应该是触发了react的在当前页面的重绘吧,就像map时的key一样,更新时不再复用node了吧?

ZhanghaoH avatar Jun 14 '22 02:06 ZhanghaoH

是的, key 更新导致组件重新渲染, 这样不推荐, 建议还是用 useRef

buuing avatar Jun 14 '22 15:06 buuing

您好,这里说的useRef是如何解决的。 我在组件componentDidUpdate里添加了onStart也不行。。

cathats avatar Sep 06 '22 08:09 cathats

最新版 @lucky-canvas/[email protected] 已修复该问题

buuing avatar Sep 30 '22 06:09 buuing