打字稿 useState:带参数的 Child 中的 SetState

Töl*_*ölz 1 typescript reactjs

感谢您的帮助。

如何将 setState 传递给子组件并使用 c 参数而不会出现打字稿错误?

父级:传递 setState

export interface State {
    value1: string;
    value2: string;
}

const Parent = () => {
    const [state, setState] = useState<State>({
        value1: "test",
        value2: "test",
    });

    return (
        <React.Fragment>
            <Child setState={setState} />
        </React.Fragment>
    );
};

export default Parent;
Run Code Online (Sandbox Code Playgroud)

子级:使用 setState 和 c 作为参数,c 被读取并带有类型错误下划线

type Props = {
    setState: Dispatch<State>;
};

const Child: React.FC<Props> = ({ setState }) => {
    return (
        <React.Fragment>
            <button
                onClick={() => {
                    //c is read underlined: Argument of type '(c: any) => any' is not assignable 
                    //to parameter of type 'State'.
                    //Type '(c: any) => any' is missing the following properties from type 
                    //'State': value1, value2
                    setState((c) => {
                        return {
                            ...c,
                            value2: "HelloWorld",
                        };
                    });
                }}
            />
        </React.Fragment>
    );
};

export default Child;
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 15

首先,由于您使用的是函数组件,因此应该将状态分离到单独的变量中,而不是使用单个状态对象。而不是{ value1: string; value2: string; }进行两次单独的调用useState。这将简化稍后的逻辑。

const Parent = () => {
    const [value1, setValue1] = useState('test');
    const [value2, setValue2] = useState('test');

    return (
        <React.Fragment>
            <Child setValue2={setValue2} />
        </React.Fragment>
    );
};
Run Code Online (Sandbox Code Playgroud)

(请注意,Parent不需要单独的类型声明State,因为它可以自动推断)

关键是setValue2正确地在子项中输入 prop。如果将鼠标悬停setValue2在父级中的 上,您将看到其类型为:

React.Dispatch<React.SetStateAction<string>>
Run Code Online (Sandbox Code Playgroud)

这就是你需要Child的:

const Child = ({ setValue2 }: { setValue2: React.Dispatch<React.SetStateAction<string>> }) => {
    return (
        <React.Fragment>
            <button
                onClick={() => {
                    setValue2('HelloWorld');
                }}
            />
        </React.Fragment>
    );
};
Run Code Online (Sandbox Code Playgroud)


小智 7

尝试这个

type Props = {
    setState: React.Dispatch<React.SetStateAction<any>>;
};
Run Code Online (Sandbox Code Playgroud)

  • 我建议不要在 TypeScript 中使用“any”——它会失去类型安全性,这有点违背了 TS 的目的。最好使类型尽可能具体。 (2认同)