reactjs 如何使用设置父数组状态值的函数记忆子组件?

ix0qys7i  于 2022-12-18  发布在  React
关注(0)|答案(2)|浏览(152)

我试图记住一个子组件,它包含一个函数,该函数设置父数组状态的值并依赖于父数组状态。然而,这意味着如果我将父数组状态作为依赖项,重新呈现的数量不会有显著改善。

const Parent = () => {
  const [state, setState] = useState([{},{},{}]);

  const setA = (index, a) => {
    let copyArr = [...state];
    copyArr[index] = a;
    setState(copyArr);
  }

  return (
   state.map((item, index)=>{
     <Child index={index} item={item} setA={setA}>
   }
  )
}

const Child = ({index, item, setA}) => {
  return (
   <View>
     <Button onClick={() => {setA(index, Math.randInt(0,100))}>
     <Text>{item.a}</Text>
   </View>
  )
}

到目前为止我尝试的是

const Parent = () => {
  const [state, setState] = useState([{},{},{}]);

  const setA = React.useCallBack((index, a) => {
    let copyArr = [...state];
    copyArr[index] = a;
    setState(copyArr);
  }, [state]);

  return (
   state.map((item, index)=>{
     <Child index={index} item={item} setA={setA}>
   }
  )
}

const Child = React.memo(({index, item, setA}) => {
  return (
   <View>
     <Button onClick={() => {setA(index, Math.randInt(0,100))}>
     <Text>{item.a}</Text>
   </View>
  )
});

然而,这并不重要,因为无论何时状态作为一个数组被更新,由于函数被重新创建,所有的兄弟组件都会重新呈现。
或者,如果我不在依赖项数组中使用state,则函数不会重新创建,状态在内部也不会改变(闭包)。
我想知道是否有一种方法可以在不对结构进行重大改革的情况下适当地实现这一目标。

2ledvvac

2ledvvac1#

不必复制当前状态,而是使用以前的状态:

const setA = React.useCallBack((index, a) => {
    setState(prevState => {
      const newState = [...prevState];
      newState[index] = a;

      return newState;
    })
  }, []);

现在,您可以从依赖项列表中移除状态

hgb9j2n6

hgb9j2n62#

1.编写泛型update(arr, index, value)函数
1.使用useCallback钩子创建记忆回调

  1. Curried function使得使用与事件数据位于同一位置的参数更加容易
    1.在setState调用中使用functional update从回调中删除所有依赖项。
// generic update array function
const update = (arr, index, value) =>
  [ ...arr.slice(0, index), value, ...arr.slice(index + 1) ]

在父组件中,我们创建记忆回调并将其传递给子组件-

const Parent = () => {
  const [state, setState] = useState([{},{},{}]);
  
  const setA = useCallback((index, a) => event =>
    setState(s => update(s, index, a))
  , []); // zero dependency callback

  return state.map((item, index)=>
    <Child key={index} item={item} index={index} onClick={setA}>
  )
}

现在Child仅在indexitem,setA更改时重新渲染-

const Child = ({ item, index, onClick }) => {
  return <View>
    <Button onClick={set(index, Math.randInt(0,100))}>Click</Button>
    <Text>{item.a}</Text>
  </View>
}

相关问题