React组件设计之依赖项

41 阅读1分钟

在设计React组件的时候,有时候需要设计一个子组件的方法依赖于外部的字段去更新,这时候需要传入depValue,举例如下

index.tsx

<Form>
 <FormItem label={"例子"} name="example">
  <ChartTypeSearch
    fetchData={fetchData}
    depValue={time}
  />
 </FormItem>
</Form>

当传入的依赖项time改变的时候,期望能重新调取接口内容

ChartTypeSearch.tsx

useEffect(() => {
    fetchData();
}, [depValue]);

但是如果time是一个数组的话,由于传入的是一个引用,这时候是会引起死循环调用fetchData的。

因此在子组件中,我们需要将依赖项做一些处理,使得子组件的兼容性更好

ChartTypeSearch.tsx
const depValueWrap = Array.isArray(depValue) ? depValue.toString() : depValue;

useEffect(() => {
    fetchData();
}, [depValueWrap]);

这里我们将depValue拍平,因此无论depValue传入的是数组还是字符串都能正确的处理,但是又引入了新的问题,如果我们传入的是对象,拍平后会变成[object Object],对象的变化无法被正确的识别,因此我们需要对数组的所有值进行拍平。

tools.ts
export const handleDepValue = (depValue) => {
  const handleDepString = (res, depValue) => {
    if (typeof depValue !== 'object') {
      res += depValue;
      return res;
    }
    if (Array.isArray(depValue)) {
      for (let i = 0; i < depValue.length; i++) {
        handleDepString(res, depValue[i]);
      }
    }
    res += JSON.stringify(depValue);
    return res;
  };

  return handleDepString('', depValue);
};

ChartTypeSearch.tsx
const depValueWrap = handleDepValue(depValue);

useEffect(() => {
    fetchData();
}, [depValueWrap]);

Set、WeepSet、Map、WeepMap用得不多,大家有需要自行扩展吧