簡體   English   中英

useMemo 不會重新渲染動態控件

[英]useMemo does not rerender dynamic controls

我有后端發送的控件列表。 有時需要更新下拉控件的選項。

我認為它會起作用。 但是,不會memoizedControls

我相信它應該像這樣工作:

  • 按下按鈕並觸發handleFieldsChange() function。
  • 然后setTechSpec('')techSpec設置為 ''
  • 然后自定義鈎子usePerson被觸發,因為它的依賴數組中有techSpec
  • 然后memoizedControls被觸發,因為它的依賴數組中有personList
  • updateControlOptions()更新controls的選項

但是,UI 沒有重新呈現, personList的新選項也沒有重新呈現。

const [techSpec, setTechSpec] = useState('1')
const [personList, isLoadingPersonList] = usePerson(techSpec)

const handleFieldsChange = (changedValue: EditablePersonValues) => {
    setTechSpec('')
    fetchPerson()}

const updateControlOptions = (
    controls: FormControl[],
    controlName: string,
    newOptions: SelectOption[],
) =>
    controls.map((control) =>
        control.name === controlName
            ? { ...control, options: newOptions }
            : { ...control },)

const memoizedControls = useMemo(() => {
    console.log('memoizedControls')
    if (personList.length > 0)
        return updateControlOptions(
            controls,
            'personId',
            personList,
        )
    return controls
}, [controls, personList])

const fetchPerson = () => {
    const localTechSpecification = form.getFieldValue('techSpecification')
    setTechSpec(localTechSpecification)
    form.setFieldsValue({ personId: undefined })
}

和:

return (
{memoizedControls.map(
        ({ name, type, displayName, required, options, measure }) => {                          
            return (
                <MyDynamicField
                    key={name}
                    name={name}
                    controlType={type}
                    displayName={`${displayName}${measure ? `, ${measure}` : ''}`}
                    required={required}
                    value={value}
                    itemOptions={options}
                />
            )
        },
    )}
)

我的問題是,當“techSpec”state 值更改時,“usePerson”掛鈎正在重新執行。 personList已更新。 但是memoizedControls不顯示personList的新值。 也許您知道為什么不重新渲染memoizedControls的原因?

拜托,有人知道我做錯了什么嗎?

import React, { useState, useMemo } from 'react';
const MyComponent = ({ personList }) => {
  const [techSpec, setTechSpec] = useState('1');
  const [isLoadingPersonList, setIsLoadingPersonList] = useState(false);

  const handleFieldsChange = (changedValue) => {
    setTechSpec('');
    fetchPerson();
  };

  const updateControlOptions = (controls, controlName, newOptions) =>
    controls.map((control) =>
      control.name === controlName
        ? { ...control, options: newOptions }
        : { ...control }
    );

  const memoizedControls = useMemo(() => {
    console.log('memoizedControls');
    if (personList.length > 0) {
      return updateControlOptions(controls, 'personId', personList);
    }
    return controls;
  }, [controls, personList]); // personList is included in the dependency array

  const fetchPerson = () => {
    const localTechSpecification = form.getFieldValue('techSpecification');
    setTechSpec(localTechSpecification);
    form.setFieldsValue({ personId: undefined });
  };

  return (
    <div>
      {memoizedControls.map(({ name, type, displayName, required, options, measure }) => (
        <DynamicField
          key={name}
          name={name}
          controlType={type}
          displayName={`${displayName}${measure ? `, ${measure}` : ''}`}
          required={required}
          value={value}
          itemOptions={options}
        />
      ))}
    </div>
  );
};

上面的代碼沒問題,問題出在組件<MyDynamicField/>

所以itemOptions應該添加到 useEffect 的依賴數組[height, width, itemOptions]) useEffect 所以代碼看起來像這樣:

export const MyDynamicField = ({
    name,
    controlType,
    displayName,
    required,
    value,
    itemOptions,
    moulds,
    initData,
    height,
    width,
}: Props) => {
    const [options, setOptions] = useState<SelectOption[]>([])

    useEffect(() => {
        const prepareOptions = filterOptions(
            name,
            moulds,
            initData,
            itemOptions,
            height,
            width,
        )
        setOptions(prepareOptions)
    }, [height, width, itemOptions])
    return (
        <ControlFactory
            key={name}
            name={name}
            controlType={controlType}
            displayName={displayName}
            required={required}
            options={options}
            value={value}
        />
    )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM