函数或useMemo的初始值最好使用什么?

时间:2019-07-08 17:27:26

标签: reactjs

我有这样一个组成部分 最好使用useState,function或useMemo的初始值。

我只知道给出useState初始值的两种方法,我给出了两个例子,但是我不确定哪种方法更好。优缺点都有什么?还是有第三种选择?

选项1

function App(yardage, arrList, indxList) {
  const [flippingListIndx, setFlippingListIndx] = useState(() => {
    const arrStart = Math.floor(indxList / yardage) * yardage;
    if (indxList < arrList.length) {
      return arrStart + yardage;
    } else {
      return arrStart - yardage;
    }
  });
  const [flippingList, setFlippingList] = useState(() => {
    const arrStart = Math.floor(indxList / yardage) * yardage;
    if (indxList < arrList.length) {
      return arrList.slice(arrStart, arrStart + yardage);
    } else {
      return arrList.slice(arrStart - yardage, arrStart);
    }
  });
  return (
    ....
  );
}

原则上,第二个选项不是初始值,但可以这样说。

选项2

function App(yardage, arrList, indxList) {
  const [flippingListIndx, setFlippingListIndx] = useState(0);
  const [flippingList, setFlippingList] = useState([]);

  useMemo(() => {
      const arrStart = Math.floor(indxList / yardage) * yardage;
      if (indxList < arrList.length) {
          setFlippingList(
              arrList.slice(
                  arrStart,
                  arrStart + yardage
              )
          );
          setFlippingListIndx(arrStart + yardage);
      } else {
          setFlippingList(
              arrList.slice(
                  arrStart - yardage,
                  arrStart
              )
          );
          setFlippingListIndx(arrStart - yardage);
      }
  }, [arrList, yardage, indxList])
  return (
    ....
  );
}

1 个答案:

答案 0 :(得分:0)

我相信这里有一个误解。 useMemo是一个用来memoize的钩子,用于提高性能,并且仅在其中一个依赖项发生更改时才会重新计算该值。像这样:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

在第二个示例中,您在调用useMemo时甚至没有存储它的返回值,它基本上不执行应有的操作,请确保您要返回一个值以“初始化” useState,但是您没有不会存储昂贵的价值或类似的东西。您所要做的就是仅在某些prop发生更改时才产生副作用,因此此处的正确钩子是useEffect。所以回到您的问题:

初始化useState

的最佳方法是什么

好吧...看一下以下情况:

const Component = () =>{
    const [value, setValue] = useState(1)

    useEffect(() =>{
       setValue(2) 
    },[])

    console.log(value)//1 and 2 next
    return <div />
}

您的控制台将显示:1、2。但是为什么呢?如果useEffect等效于componentDidMountcomponentDidUpdatecomponentWillUnmount,则值应为 在第一个console.log通话之前被覆盖,对吗?但是组件(无论是否基于类)实际上都会有一个额外的render,甚至在componentDidMount之前也会被调用。因此流程如下:第一个渲染将显示直接在useState内部完成的初始化,第二个渲染将显示通过效果更新的值,因此上面的代码等效于:

class ClassComponent extends React.Component{
    state = {
        value : 1
    }

    componentDidMount(){
        const value = 2
        this.setState({ value })
    }

    render(){
        console.log(this.state.value) // 1, 2
        return <div />
    }
}

实际上只有一种初始化useState的方法,因为它的初始化发生在副作用之前。因此请记住,useState就像正常状态声明一样,useEffect就像生命周期挂钩一样,请在这种情况下忘记useMemo并使用副作用来更新状态值基于prop的更改。