热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AntdesignChartonReady函数使用外部变量问题

一、问题描述封装了一个C

一、问题描述

封装了一个Chart组件,它接收一个boolean类型的props,根据这个boolean的true或false执行不同的操作。经过console.log验证,onReady函数只会在组件初次渲染时取到props值,不管后面的props变化成什么都无法重新取值。

二、代码描述

初始化状态为0,useRequest拿到后端的值为1。

传递给Chart组件的props,是可以拿到最新的,可以在40行的打印中看到。

但是onReady挂载的坐标轴点击事件打印出的却不会变化,依然是0。

// 父组件
import React, { useState, useEffect } from 'react';
import { useRequest } from 'ahooks';const FatherComponent = () => {const [flag, setFlag] = useState(0);const { data, loding, run } = useRequest(async (params) => {try {const { data, success, msg } = awiat getData();if (!success) {return [];}setFlag(data.flag)return data;} catch(e) { console.log(e) };return [];}, { manual: true })useEffect(() => {if (!isUndefined(data)) {setFlag(data.flag)}}, [data])return (

{data && }
)
}
export default FatherComponent;// 子组件
import React from 'react'
import { Column } from "@ant-design/plots";const ChildChartComponent = (props) => {const { data, flag } = props;console.log(flag)const config = {data,// ...many config settings, it's unimportantonReady: (plot) => {plot.on("axis-label:click", (e) => {if (Number(flag) === 1) {console.log('执行props.flag为true的逻辑');} else {console.log('执行props.flag为false的逻辑');}})}}return ()
}
export default ChildChartComponent;

三、原因解析

这个问题研究了整整一天,换了很多种方式都寻找不到问题所在。

一开始想是我得状态不对,再之后是觉得是最新的onReady没有被重新赋值给chart组件。

在官方文档中没找到相关问题描述,于是乎,我打开Github进入到组件仓库,在issues里找Bug和提问,终于被我找到跟我有相关问题的同志。

原来是因为onReady()函数是一个闭包,在子组件初次渲染的时候,它保存的值是初始值0,所以一直拿不到新状态。

四、修改子组件的写法,利用useRef解决闭包问题

我们声明一个ref,在effect中的deps校验规则设置为flag,effect方法内将ref的current每一次都指向flag。

将onReady中的on方法内的通过flag判断改为通过flagRef.current判断即可。

useRef可以解决闭包问题的原因在于: useRef 返回的是 { current: null },将对应数据赋值给 current,在声明之后,引用地址是不变的。

// 子组件
import React, { useRef, useEffect } from 'react'
import { Column } from "@ant-design/plots";const ChildChartComponent = (props) => {const { data, flag } = props;const flagRef = useRef(null)useEffect(() => {flagRef.current = flag;}, [flag])const config = {data,// ...many config settings, it's unimportantonReady: (plot) => {plot.on("axis-label:click", (e) => {if (Number(flagRef.current) === 1) {console.log('执行props.flag为true的逻辑');} else {console.log('执行props.flag为false的逻辑');}})}}return ()
}
export default ChildChartComponent;


推荐阅读
author-avatar
精神还没分裂2011
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有