You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用API时React Quill的defaultValue无法正常显示

React Quill 无法用API数据预填充内容的解决方案

问题根源

  1. React Quill 属性错误:你给React Quill传了自定义的state属性,但React Quill本身是用value实现受控模式的,state属性完全无效,导致数据更新时编辑器无法同步。
  2. defaultValue仅初始化生效:defaultValue只会在组件第一次渲染时赋值,而API数据是异步返回的,等数据回来时组件已经挂载完成,defaultValue不会触发编辑器更新。
  3. useEffect执行顺序问题:你先调用getIsp再设置urlId,第一次执行getIsp时urlId是空字符串,可能导致查询参数错误(虽你说能拿到数据,但逻辑上存在隐患)。

修复步骤

1. 修正 EditorComponent,使用官方受控属性

把自定义的state参数换成value,这是React Quill官方支持的受控属性:

import React from 'react';
import ReactQuill from 'react-quill';

const modules = {
  toolbar: [
    [{ font: [] }],
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    ['bold', 'italic', 'underline', 'strike'],
    [{ color: [] }, { background: [] }],
    [{ script: 'sub' }, { script: 'super' }],
    ['blockquote', 'code-block'],
    [{ list: 'ordered' }, { list: 'bullet' }],
    [{ indent: '-1' }, { indent: '+1' }, { align: [] }],
    ['link', 'image', 'video'],
    ['clean']
  ]
};

const EditorComponent = ({ placeholder, value, onChange, defaultValue }) => {
  return (
    <ReactQuill
      defaultValue={defaultValue}
      value={value}
      modules={modules}
      theme='snow'
      placeholder={placeholder}
      onChange={onChange}
    />
  );
};

export default EditorComponent;

2. 调整 UpdateISPEntry 组件的状态管理与 useEffect 逻辑

  • 在API请求完成时直接同步编辑器状态;
  • 修复useEffect执行顺序,先设置urlId再调用查询;
  • 用受控模式(value={notesState})让编辑器和状态同步:
const UpdateISPEntry = () => {
  const [formValues, setFormValues] = useState();
  const [urlId, setUrlId] = useState('');
  const [previousState, setPreviousState] = useState();
  const [notesState, setNotesState] = useState(); // 编辑器受控状态

  const [getIsp, { data, loading, error }] = useLazyQuery(GET_ISP_ENTRY, {
    variables: {
      ispListEntryId: urlId
    },
    onCompleted: () => {
      const notesData = data?.ispListEntry?.notes;
      setNotesState(notesData); // 直接同步到编辑器状态
      setFormValues(data?.ispListEntry);
    },
    onError: () => {
      toast.error(error);
    }
  });

  console.log(loading ? 'Loading...' : data?.ispListEntry?.notes);

  const [
    submitValues,
    { data: successful, loading: successLoading, error: loadingError }
  ] = useMutation(UPDATE_ISP_ENTRY, {
    onError: () => {
      toast.error(`There was an error ${loadingError}`);
    }
  });

  const params = useLocation();
  const path = params.pathname;
  const pathSplit = path.split('/')[2];

  useEffect(() => {
    // 先设置urlId,再调用查询
    setUrlId(pathSplit);
    if (pathSplit) { // 确保pathSplit有效再发起查询
      getIsp();
    }
  }, [pathSplit, getIsp]); // 移除不必要的依赖,避免无限循环

  const handleSubmit = () => {};

  return (
    <Fragment>
      <div className='container p-4 parent-container'>
        <ISPFormHeader />
        <ISPFormHeaderPagename children='Update ISP Entry' />
        <ISPForm
          initialValues={data?.ispListEntry}
          enableReinitialize={true}
          onSubmit={handleSubmit}
        />
        <div className='editor-fields'>
          <EditorComponent
            value={notesState} // 用受控属性value绑定状态
            onChange={setNotesState}
            placeholder='Enter Notes Here'
          />
        </div>
        <div className='editor-fields'>
          <EditorComponent
            placeholder='Enter Previous Notes Here'
            value={previousState}
            onChange={setPreviousState}
          />
        </div>
      </div>
    </Fragment>
  );
};

export default UpdateISPEntry;

额外说明

如果你不想用受控模式,也可以给EditorComponent加一个key,当API数据更新时改变key,强制组件重新渲染,让defaultValue重新生效:

<EditorComponent
  key={data?.ispListEntry?.notes ? 'notes-loaded' : 'notes-empty'}
  defaultValue={data?.ispListEntry?.notes}
  onChange={setNotesState}
/>

但受控模式是React Quill推荐的用法,稳定性更高。

内容的提问来源于stack exchange,提问作者timbo245

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:25:35