简体   繁体   English

如何从一个子组件在父组件中设置 state 并使用 react 和 typescript 在另一个子组件中访问 state?

[英]How to set state in parent from one child component and access the state in another child component using react and typescript?

i want to set the state in Parent component on clicking a button in child component.我想在单击子组件中的按钮时在父组件中设置 state。 Also i want to access this state in other child component.我也想在其他子组件中访问这个 state。

what i am trying to do?我想做什么? On clicking upload button (UploadButton component) i want the state isDialogOpen to be set to true.单击上传按钮(UploadButton 组件)时,我希望将 state isDialogOpen 设置为 true。 and i want to access isDialogOpen state in UserButton component.我想在 UserButton 组件中访问 isDialogOpen state 。

below is the snippet,下面是片段,

function Main() {
    return (
        <Wrapper>
            <React.Suspense fallback={null}>
                <Switch>
                    <Route
                        exact
                        path="/page1"
                        render={routeProps => (
                            <Layout>
                                <React.Suspense fallback={<PlaceHolder></>}>
                                    <child1 {...routeProps} />
                                </React.Suspense>
                            </Layout>
                        )}
                    />
                    <Route
                        exact
                        path="/page2"
                        render={routeProps => (
                            <Layout>
                                <Child2 {...routeProps} />
                            </Layout>
                        )}
                    />
                </Switch>
            </React>
        </Wrapper>
    )
}


function Child1() {
    return (
        <UploadButton/>
    );
}

type Props = RouteComponentProps<{ itemId: string; productId: string }>;

function UploadButton({ match }: Props) { //here i set the state isDialogOpen
    const [isDialogOpen, setDialogOpen] = React.useState(false);

    const handle_click = () => {
        setDialogOpen(!isDialogOpen);
    };

    return (
        <>
            <Button onClick={handle_click}/>

            {isDialogOpen && (
                <UploadForm/>
            )}
        </>
    );
}


function Child2() {
    return (
        <UserButton/>
    );
}

function UserButton() {
    return (
        <Icon/>
    );
}

In the above snippet, isDialogOpen state is set in UploadButton component.在上面的代码片段中,在 UploadButton 组件中设置了 isDialogOpen state。

Now i want to modify above snippet such that the Icon component in UserButton component is hidden if isDialogOpen is true.现在我想修改上面的代码片段,如果 isDialogOpen 为真,则隐藏 UserButton 组件中的 Icon 组件。

i want to access this isDialogOpen state in UserButton component.我想在 UserButton 组件中访问这个 isDialogOpen state。

what i have tried?我试过什么?

I can define a function in main component that sets isDialogOpen to true when Upload button is clicked in UploadButton component.我可以在主组件中定义一个 function 当在 UploadButton 组件中单击 Upload 按钮时将 isDialogOpen 设置为 true。 but this needs passing the function as prop from main component to Upload Button and similarly passing the state to UserButton from main component.但这需要将 function 作为道具从主组件传递到上传按钮,同样将 state 从主组件传递给 UserButton。

Is there some neat way to do this?有没有一些巧妙的方法可以做到这一点? i am new to typescript and react.我是 typescript 的新手并做出反应。 could someone help me solve this.有人可以帮我解决这个问题。 thanks.谢谢。

You should define state value and function which update state as props respectively to child components as props.您应该将 state 值和 function 定义为分别将 state 更新为道具,将子组件作为道具。 You can take example of the code which I provide bellow您可以以我在下面提供的代码为例

 const Child1 = (props) => { return <div>This is the counter value {props.counter}</div> } const Child2 = (props) => { return <div> <h2>Here the button to update the counter</h2> <button onClick={props.update}> Update counter state in the parent </button> </div> } class MainComponent extends React.Component { constructor(props) { super(props); this.state = { counter: 0 } } updateCounter = () => { this.setState({counter: this.state.counter + 1}); } render() { return <div> <Child1 counter={this.state.counter} /> <Child2 update={this.updateCounter} /> </div> } } ReactDOM.render(<MainComponent />, document.getElementById('root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

You can use the same component with context API and React HOOKS like this您可以将相同的组件与上下文 API 和 React HOOKS像这样使用

import React, { useContext, useState} from 'react';

const CounterContext = React.createContext({
    counter: 0
});

const MainComponent  = (props) => {
    const [counter, setCounter] = useState(0);
    
    const updateCounter = () => {
        setCounter(counter + 1);
    }

    return <CounterContext.Provider value={
        counter,
        update: updateCounter
    }>
        <div>
            <Child1 />
            <Child2 />
        </div>
    </CounterContext.Provider>;
}


const Child1 = (props) => {
    const counter = useContext(CounterContext);
    return <div>This is the counter value {counter.counter}</div>
}

const Child2 = (props) => {
    const counter = useContext(CounterContext);

    return <div>
        <h2>Here the button to update the counter</h2>
        <button onClick={counter.update}>
            Update counter state in the parent
        </button>
    </div>
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM