【react】记录一次react组件props依赖异步数据(setFieldsValue)后传递form给子组件,再逐层传递给孙子组件引起的未渲染异常

背景

react祖父组件设置异步数据(setFieldsValue)后传递form给子组件,再逐层传递给孙子组件引起的未渲染异常,孙子组件如果不设置useEffect和useState去监听value的值进行重渲染,会出现获取得到value最新值,但是不进行渲染的异常

解决前后的代码对比

完整代码(异常):
javascript 复制代码
const GetText = (props) => {
  const { value, config, containerId, getFieldValue } = props;
  const [itemValue, setItemValue] = useState(value);
  const { formId } = config;
  const getFormId = useCallback(
    (suffix = '_param_countryPhoneCode') => {
      if (Array.isArray(formId)) {
        return [containerId, formId[0], `${formId[1]}${suffix}`];
      }
      return `${formId}${suffix}`;
    },
    [formId, containerId],
  );
  
  useEffect(() => {
    const pObj = getFieldValue(getFormId()) || {};
    if (!value.includes('+')) {
      const _itemValue = `${pObj.countryPhoneCode ? '+' : ''}${pObj.countryPhoneCode} ${value}`;
      setItemValue(_itemValue);
    }
  }, [getFieldValue, getFormId, value, getFieldValue(getFormId())]);

  return itemValue ? (
    <>
      <div style={{ fontSize: 12 }}>{itemValue}</div>
    </>
  ) : null;
};
完整代码(正常):
javascript 复制代码
const GetText = (props) => {
  const { value, config, containerId, getFieldValue } = props;
  const [itemValue, setItemValue] = useState();
  const { formId } = config;
  const getFormId = useCallback(
    (suffix = '_param_countryPhoneCode') => {
      if (Array.isArray(formId)) {
        return [containerId, formId[0], `${formId[1]}${suffix}`];
      }
      return `${formId}${suffix}`;
    },
    [formId, containerId],
  );

  // 注意,由于在changeRecordModal中有对变更记录表单项做了顺序标记,
  // 因此formId会多一个序号,在变更记录弹窗里,首次加载可能因为更新是异步的导致value没有正常渲染,
  // 所以这边必须借用useEffect和useState控制value的更新渲染
  useEffect(() => {
    const pObj = getFieldValue(getFormId()) || {};
    if (!value.includes('+')) {
      const _itemValue = `${pObj.countryPhoneCode ? '+' : ''}${pObj.countryPhoneCode} ${value}`;
      setItemValue(_itemValue);
    }
  }, [getFieldValue, getFormId, itemValue, value]);

  return itemValue ? (
    <>
      <div style={{ fontSize: 12 }}>{itemValue}</div>
    </>
  ) : null;
};
相关推荐
别动我齐刘海2 分钟前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝1 小时前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
刘发财1 小时前
前端如何生成10000页PDF文件?
前端·javascript·开源
A接拉起0072 小时前
2026 年 JavaScript 开发者需要了解的知识
前端·javascript·后端
_馒头2 小时前
pixiJs游戏开发实践 - 跳棋小游戏
javascript·vue.js
用户11481867894842 小时前
面试官:大屏项目里十几个模块同时渲染上万条数据,怎么做到不卡?
前端·性能优化
前端市界2 小时前
Pro React Admin: 统一工程底座,承载多种应用...
前端·github
葡萄城技术团队2 小时前
dsh-spreadjs-editor 当前支持什么:安装前需要了解的几件事
前端
三*一3 小时前
优化修整算法
前端·javascript·算法
楠楠子呀3 小时前
英语、西语、阿语客户各开一个口:多语言获客的分流方案
开发语言·javascript·ecmascript·跨境电商·whatsapp·营销工具