antvis / F2

📱📈An elegant, interactive and flexible charting library for mobile.
https://f2.antv.vision/zh
MIT License
7.89k stars 649 forks source link

微信小程序使用Component组件,父页面state更新后,图表组件监听不到willReceiveProps,无法更新数据 #1465

Closed tayy10 closed 2 years ago

tayy10 commented 2 years ago

微信小程序使用Component组件,父页面state更新后,图表组件监听不到willReceiveProps,无法更新数据 父组件: 通过<f ec={this.state.ec} />传递生成组件的函数renderChart

renderChart() {
    const { percent } = this.state
    return <Gauge 
      percent={percent}
    />
  }

图表组件中监听不到props的更新,只能过去到第一次传递过去的props

willReceiveProps(nextProps) {
        // this.updater.enqueueForceUpdate(_t, {percent: 0.2, endAngle: Math.PI * 2})
        super.willReceiveProps(nextProps)
        console.log(nextProps)
    }
zengyue commented 2 years ago

贴一下完整的示例?

tayy10 commented 2 years ago

贴一下完整的示例?

父页面:

import React, { Component } from 'react'
import Taro, { Config } from '@tarojs/taro'
import { View } from '@tarojs/components'
import Gauge from '../../components/gauge/gauge'

class SetTemp extends Component {
  constructor(props) {
    super(props)
    this.state = {
      percent: 0.5,
      ec: {
        renderChart: this.renderChart.bind(this)
      }
    }
  }
  componentDidMount () {
    const _t = this
    setTimeout(() => {
      _t.setState({
        percent: 0.2
      })
    }, 2000)
  }
  renderChart() {
    const { percent } = this.state
    return <Gauge 
      percent={percent}
    />
  }
  render () {
    return (
      <view className={style.setTemp}>
            <f ec={this.state.ec} />
      </view>
    )
  }
}
export default SetTemp

图表组件:

import { Component } from '@antv/f2';

class Gauge extends Component {
    constructor(props, context, updater) {
        super(props, context, updater)
        const { percent } = this.props
        const endAngle = Math.PI * ( 1 + percent )
        this.state = {
            centerX: 0, 
            centerY: 0,
            startAngle: Math.PI,
            endAngle,
            percent,
            r: '200px'
        }
    } 
    willMount() {
        const { left, top, width, height } = this.context,
            centerX = left + width / 2,
            centerY = top + height /2
        this.setState({
            centerX,
            centerY
        })
    }
    willReceiveProps(nextProps) {
        // this.updater.enqueueForceUpdate(_t, {percent: 0.2, endAngle: Math.PI * 2})
        super.willReceiveProps(nextProps)
        const { props: lastProps } = this,
            { percent: nextData } = nextProps,
            { percent: lastData } = lastProps
        if(nextData !== lastData) {
            this.changeAngle(nextData)
        }
    }
    changeAngle(percent) {
        const { startAngle } = this.state,
            endAngle = startAngle * (1 + percent)
        this.setState({
            percent,
            endAngle
        })
    }
    render() {
        const { centerX, centerY, r, startAngle, endAngle } = this.state
        return (
            <group>
                <arc 
                    attrs={{
                        x: centerX,
                        y: centerY,
                        r,
                        startAngle,
                        endAngle,
                        lineWidth: '20px',
                        lineCap: 'round',
                        stroke: '#fff'
                    }}
                    animation={{
                        appear: {
                            duration: 500,
                            easing: 'linear',
                            property: ['endAngle']
                        },
                        update: {
                            duration: 500,
                            easing: 'linear',
                            property: ['endAngle']
                        }
                    }}
                /> 
            </group>  
        )
    }
}

export default Gauge

image 只能渲染第一次传递过去的{percent: 0.5},通过setTimeout更新的state无法传递过去

zengyue commented 2 years ago

好的,我迟点看下

zengyue commented 2 years ago

有没有完整的工程,跑不起来

tayy10 commented 2 years ago

有没有完整的工程,跑不起来

https://gitee.com/fuckingHelloWorld/f2_test

yarn dev:weapp

tayy10 commented 2 years ago

有没有完整的工程,跑不起来

知道是哪里的问题了。可以通过f2-wx封装的canvas实例,调用update方法更新,还是谢谢大神。 只需要在封装的插件里面添加一个observers,在组件里面就可以接收到props的更新了。

observers: {
    "percent": function(percent) {
        this.canvas && this.canvas.update({
           children: this.data.ec.renderChart()
    })
  }
}