简体   繁体   中英

How to set the state using context.provider in react and typescript?

i am using context.provider usecontext reacthook to show a dialog. i set this around MainComponent. For the value attribute of context.provider i get error type {setDialogOpen(Open: boolean) => void} is not assignable to type boolean.

what i am trying to do? I want to display a dialog when user clicks either a button in home or books component. on clicking hide button in dialog the dialog shouldnt be open.

below is my code,

function MainComponent() {
    const DialogContext = React.createContext(false);
    let [showDialog, setShowDialog] = React.useState(false);
    return (
        <DialogContext.Provider value={{ 
            setDialogOpen: (open: boolean) => setShowDialog(open)}}>//get error
            {showDialog && <Dialog DialogContext={DialogContext}/>
            <Route 
                path="/items">
                <Home DialogContext={DialogContext}/>
            </Route>
            <Route
                path="/id/item_id">
                <Books DialogContext={DialogContext}/>
            </Route>
        </DialogContext.Provider>
    )
}

function Home({DialogContext} : Props) {
    const dialogContext= React.useContext(DialogContext);
    const handleClick = (dialogContext: any) {
        dialogContext.setDialogOpen(true);
    }
    return ( 
        <button onClick={handleClick(dialogContext)}>button1</button>
    )
}

function Books({DialogContext} : Props) {
    const dialogContext= React.useContext(DialogContext);
    const handleClick = (dialogContext: any) {
        dialogContext.setDialogOpen(true);
    }
    return ( 
        <button onClick={handleClick(dialogContext)}>button2</button>
    )
}

function Dialog({DialogContext}: Props) {
    return(
        <div>
            //sometext
            <button> hide</button>
        </div>
    )
 }

I have tried something like below,

return (
    <DialogContext.Provider value={{ 
        setShowDialog(open)}}>//still get a error
            {showDialog && <Dialog DialogContext={DialogContext}/>
)

Could someone help me fix this or provide a better approach to show the dialog on clicking a button in home and books component using usecontext hook. thanks.

There are few issues that you have to fix in your code.

  • You are creating context with the default value of false . Then later you try to override it to an object and hence the type error.
  • To fix the issue, create & export the context in separate file/helper. Don't pass them down as props.
  • import the context in parent and child components.
  • your handleClick fun in child component is missing an arrow .
  • the button onClick in child component is directly calling the function. You should pass just the function reference.

See the updated code with corrections below.

context helper

...
type ContextProps = { 
    setDialogOpen?: (open: boolean) => void,
  };
export const DialogContext = React.createContext<ContextProps>({});

MainComponent

import {DialogContext} from '../contextHelper';
function MainComponent() {
    // const DialogContext = React.createContext(false); //<---- remove this
    let [showDialog, setShowDialog] = React.useState(false);
    return (
        <DialogContext.Provider value={{ 
            setDialogOpen: (open: boolean) => setShowDialog(open)}}>
...

Home & Book Component

import {DialogContext} from '../contextHelper';
function Home() {
    const dialogContext= React.useContext(DialogContext);
    const handleClick = () => {
        dialogContext.setDialogOpen(true);
    }
    return ( 
        <button onClick={handleClick}>button1</button>
    )
}

import {DialogContext} from '../contextHelper';
function Books() {
    const dialogContext= React.useContext(DialogContext);
    const handleClick = () => {
        dialogContext.setDialogOpen(true);
    }
    return ( 
        <button onClick={handleClick}>button2</button>
    )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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