【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;
};
相关推荐
cindershade6 小时前
用原生 HTML5 视频与 Canvas 实现浏览器端视频抽帧封面
前端
笨鸟先飞,勤能补拙6 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
NutShell Wang6 小时前
Wails v3 Beta 实战:用显式对象模型重写你的第一个 Go 桌面应用
前端·人工智能·go·vibe coding
daols886 小时前
vue 甘特图 vxe-gantt 任务条拖拽自动更新日期
javascript·vue.js·甘特图
cindershade6 小时前
前端国际化工程实践:语言包拆分、动态加载与日期数字格式统一
前端
kisbad6 小时前
Day 036|OpenAI Agents SDK 快速开始:今天跑通第一个 Agent
java·前端·javascript
qq_267612896 小时前
Gitee CodePecker行业场景化落地指南:金融、车联网与IoT双引擎选型与工程化路径
前端·gitee·自动化
初晨未凉6 小时前
elementui自定义内容图片预览
前端
无糖可可果7 小时前
从零读懂一个 Next.js 全栈笔记应用
前端
Maxkim7 小时前
DeepSeek Harness 源码深度分析:像 VS Code 一样插件化的 Agent 框架
前端·架构