1

我有一个数组,它作为道具提供给我的名为Child. 现在,每次将新项目添加到数组时,都应该针对 API 进行提取。

这个数组保存在一个Parent使用useState钩子命名的组件中。每当我想添加一个新项目时,我都必须重新创建数组,因为我不允许直接对其进行变异。

我试图在以下代码片段中简化我的用例:

const Parent = () => {
    const [array, setArray] = useState([]);

    ///...anywhere
    setArray(a => [...a, newItem]);

    return <Child array={array} />;
}

const Child = ({ array }) => {
    useEffect(() => {
        array.forEach(element => {
            fetch(...);    
        });
    }, [array]);

    return ...;
}

现在,我的问题是:我怎样才能从我的 API 中只为新元素而不是整个数组获取新数据?

我希望我足够好地描述了我的问题。如果有任何不清楚或遗漏的地方,请告诉我。

4

2 回答 2

1

如何取而代之的是获取 API 数据Parent并将最终结果传递给Child?这种重构会带来一些好处:

像下面的例子这样的东西已经可以做你想做的了——通过onClick(或以其他方式)添加一个项目,获取它的数据并将整个数组传递给 Child:

const Parent = () => {
  const [array, setArray] = useState([]);

  return (
    <div onClick={addItem}>
      <Child array={array} />;
    </div>
  );

  function addItem(e) {
    const item = createItemSomehow(...)
    fetch(...).then(data => setArray([...array, { item, data }]));
  }
};

更新:

如果你想保持你的结构和 API 不变,另一种方法是用usePrevious钩子记住你的 Child 中的先前数组 prop 并查找项目更改。

const Child = ({ array }) => {
  const prevArray = usePrevious(array);
  useEffect(() => {
    if (array !== prevArray && array.length) {
      //fetch(...)
      console.log(`fetch data for index ${array.length - 1}`);
    }
  });
  return (...);
};

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

密码沙盒

于 2019-08-23T10:00:48.167 回答
0

例如,您可以保留以前获取的项目的列表。

const Child = ({ values }) => {

  const [fetched, setFetched] = useState([]);

  useEffect(() => {
    values.forEach(v => {
      if (!fetched.includes(v)) {
        setFetched(fetched => [...fetched, v]);
        fetch(v);
      }
    });
  }, [values, logged]);

https://codesandbox.io/s/affectionate-colden-sfpff

于 2019-08-23T07:25:49.400 回答