【问题标题】:how can i get child state value to parent using useRef in reactjs + typescript (hooks)我如何在 reactjs + typescript (钩子)中使用 useRef 将子状态值传递给父级
【发布时间】:2020-12-30 01:35:10
【问题描述】:

我是 Typescript 的新手。我需要在单击按钮时使用 ref 将子状态值传递给父级以更新 reducer 值。

我尝试将ref 传递给孩子,但我收到类似以下的错误:

类型'{值:字符串; onChange: 调度;参考: MutableRefObject; }' 不能分配给类型'IntrinsicAttributes & Props & { children?: ReactNode; }'。

类型'IntrinsicAttributes & Props & { children?: ReactNode; 上不存在属性'ref' }'.ts(2322)

父组件

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;

【问题讨论】:

  • 你在哪里使用 useRef?我在上面的代码中没有看到它
  • 我已经删除了,因为它破坏了我的工作,我只需要在钩子中使用 typescript 的解决方案来获取子状态值

标签: reactjs typescript react-hooks


【解决方案1】:

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

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

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

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 将子状态值传递给父级以更新 reducer 值。

只需传递一个回调!状态是否应该存储在孩子中,或者你可以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
       }} />
...

【讨论】:

    【解决方案2】:

    一个更简单的方法是使用 React 内置的 useRef 钩子和保留的 ref 属性。它仅适用于可变对象,因此您不必担心自己输入。

    import { useRef } from "react";
    
    export const CreateEvent = (props: any) => {
    
        const welcomeRef = useRef();
    
        return (
            <Page title='Dashboard'>
                <ErrorBoundary>
                    {(() => {
                        switch (activeEventStage?.step) {
                            case 1:
                                return (
                                    <ErrorBoundary>
                                        <Welcome ref={welcomeRef} />
                                    </ErrorBoundary>
                                );
                            default:
                                return null;
                        }
                    })()}
                </ErrorBoundary>
            </Page>
        );
    };
    export default withRouter(CreateEvent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 2020-09-09
      • 2021-06-30
      • 2021-12-26
      • 1970-01-01
      • 2021-04-25
      • 2019-03-08
      • 1970-01-01
      相关资源
      最近更新 更多