我如何在reactjs +打字稿中使用useRef将子状态值赋给父级(挂钩)

时间:2020-09-11 13:58:07

标签: reactjs typescript react-hooks

父组件

        import React, from "react";
        import styled from "styled-components";
        import {
        Page,
        Welcome,
        ErrorBoundary
        } from "components";
        const ParentDiv = styled.div`
        margin: 0 410px 30px 15px;
        `;

        export const CreateEvent = (props: any) => {

        return (
            <Page title='Dashboard'>
            <ErrorBoundary>
                {(() => {
                switch (activeEventStage?.step) {
                    case 1:
                    return (
                        <ErrorBoundary>
                        <Welcome />
                        </ErrorBoundary>
                    );
                    default:
                    return null;
                }
                })()}
            </ErrorBoundary>
            </Page>
        );
        };
        export default withRouter(CreateEvent);

子组件

        import React, { useState } from "react";
        import { Row, Col } from "react-bootstrap";

        export const Welcome = () => {
        const { t } = useTranslation();
        const [state, setState] = useState({
            welBannerTagline: "",
            welHeroTitle: "",
        });

        return (
            <CreateEventFormContainer
            title={t("event.create.title")}
            subTitile={t("welcome.subTitle")}
            >
            <>
                <Row>
                <Col lg='6'>
                    <DropZoneInputField
                    titleName={t("welcome.bgImage.title")}
                    onSelectedFiles={onDropFiles}
                    imageType='bgImage'
                    value={state.welBgFilename}
                    />
                </Col>
                <Col lg='6'>
                    <DropZoneInputField
                    titleName={t("welcome.banner.title")}
                    onSelectedFiles={onDropFiles}
                    imageType='bannerImage'
                    value={state.welBannerFilname}
                    />
                </Col>
                </Row>
            </>
            </CreateEventFormContainer>
        );
        };
        export default Welcome;

typeript的新功能,需要使用单击按钮上的ref来获取子级状态值给父级以更新化简器值 我已经尝试过但收到与此类似的错误

输入'{value:string; onChange:Dispatch ;参考:MutableRefObject ; }' 不能分配给'IntrinsicAttributes&Props&{children ?: ReactNode; }'。 属性'ref'在类型'IntrinsicAttributes&Props&{children ?: ReactNode; }'。ts(2322)

1 个答案:

答案 0 :(得分:0)

您收到该错误是因为 Welcome 并非旨在接受 ref 道具。

ref 是 React 中的保留道具名称,因此为了将道具 ref 传递给子组件,该子组件必须使用 React.forwardRef 来接受 ref 道具.

您可以使用任何其他道具名称直接传递 ref 对象,例如 myRef。在这种情况下,您不需要使用 forwardRef,但您确实需要确保孩子的 props 接受一个 prop myRef,它是一个 ref。 >

ref 本身的类型取决于它将最终附加到 DOM 的位置。可能是 HTMLButtonElement

interface WelcomeProps {
    myRef: React.MutableRefObject<HTMLButtonElement | null>;
}

export const Welcome = ({myRef}: WelcomeProps) => {
...
export const CreateEvent = (props: RouteComponentProps) => {
    const refObject = React.useRef<HTMLButtonElement | null>(null);
    return (
...
       <Welcome myRef={refObject}/>
...

这允许您与 DOM 进行交互。但这似乎不是您真正想要做的。

<块引用>

我需要在单击按钮时使用 ref 将子状态值传递给父级以更新减速器值。

只需传递一个回调!状态是否应该存储在子进程中,或者您可以lift it up 到父进程吗?

interface CallbackValue {
    // what properties does the callback want to receive?
    welBannerTagline: string;
    welHeroTitle: string;
}

interface WelcomeProps {
    myCallback: (value: CallbackValue) => void;
}

export const Welcome = ({myCallback}: WelcomeProps) => {
    const [state, setState] = useState({
        welBannerTagline: "",
        welHeroTitle: "",
    });

    const handleEvent = () => {
        myCallback(state);
    }
...
export const CreateEvent = (props: RouteComponentProps) => {
    return (
...
       <Welcome myCallback={(value) => {
           // do something here with the value
       }} />
...