如何使用打字稿传递数字数组并做出反应

时间:2020-07-15 14:28:50

标签: reactjs typescript react-hooks

我第一次在React中使用Types,但我对此不太熟悉。

我正在尝试将子组件中的表单中的数字添加到数字数组中。

因此,我创建了一个useState挂钩:

const [valuesList, setValuesList] = useState<number[]>([]);

现在我正在尝试将setValuesList挂钩传递给子组件:

<AddNum
        setValues={setValuesList}
      />

在子组件中,我为道具定义了一个接口:

interface AppProps {
  setValues: (value: number) => void;
}

但是,当我尝试调用setValues挂钩时:

const addNumber = (value: string): undefined => {
const num = parseInt(value);
props.setValues((prevList) => prevList.concat(num));
return undefined;

};

我在父组件中遇到此错误:

/Users/acandael/Tutorials/react/add-nums/src/components/AddNum.tsx
TypeScript error in /Users/acandael/Tutorials/react/add-nums/src/components/AddNum.tsx(21,21):
Argument of type '(prevList: any) => any' is not assignable to parameter of type 'number[]'.
  Type '(prevList: any) => any' is missing the following properties from type 'number[]': pop, push, concat, join, and 27 more.  TS2345

    19 |   const addNumber = (value: string): undefined => {
    20 |     const num = parseInt(value);
  > 21 |     props.setValues((prevList) => prevList.concat(num));
       |                     ^
    22 |     return undefined;
    23 |   };
    24 | 

有人知道如何将子组件中的数字添加到父组件中的数字数组,并使TypeScript保持快乐吗?

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您正在尝试通过调用props.setValue(num)将数字数组的状态值更改为数字

接口setValuesAppProps的类型定义也不正确。 TS会将设置函数setValuesList的类型推断为React.Dispatch<SetStateAction<number[]>>,与类型(value: number) => void不兼容。

如果您想将函数setValues作为道具传递,则setValuesList函数的正确定义是

interface AppProps {
   setValues: React.Dispatch<SetStateAction<number[]>>
 
   // setValues: (numArr: number[]) => void  ( this will work as well )
}

更新状态valuesList的解决方案是使用函数更新或创建另一个回调函数,该回调函数接收一个number作为参数并更新状态。

具有功能更新

setValues(prev => prev.concat(num))

使用setValues作为其他回调函数

// with this solution you don't need to modify the interface AppProps

interface AppProps {
   setValues: (num: number) => void
}

const Foo: React.FC<AppProps> = ({ setValues }) => {
  
  // component logic
  
  return (
   <>
   </>
  )
}

// in parent component
const [valuesList, setValuesList] = useState<number[]>([])

const updateWithNewValue = useCallback((num: number) => {
   setValuesList(prev => prev.concat(num))
}, [])

// pass the updateWithNewValue as props

<Foo setValues={updateWithNewValue}/>

codesandbox

中的类似示例