TransWikia.com

How to call useState from another Page?

Stack Overflow Asked by Grizzly Bear on December 7, 2021

Bascially whenever I deleted an item in my handleDelete function it would route back to the homePage and I wanted to display a message that says your product succesully deleted for about 5 seconds.

In my index.js I first set message to false. and inside my ProductAttribute whenever I click it the set message will be true and will show the message in Index.js/ in my UI.

my handleDelete function

import React, { useState } from "react";
import { Header, Button, Modal } from "semantic-ui-react";
import axios from "axios";
import baseUrl from "../../utils/baseUrl";
import { useRouter } from "next/router";

function ProductAttributes({ description, _id }) {
    const [modal, setModal] = useState(false);
    const router = useRouter();

async function handleDelete() {
    const url = `${baseUrl}/api/product`;
    const payload = { params: { _id } };
    await axios.delete(url, payload);
    router.push("/");
    setMessage(true);
    setTimeout(function () {
        setMessage(false);
    }, 5000);
}

while in my Index.js. The setMessage in my useState isn’t getting called from ProductAttributes file.

import React, { useEffect, useState } from "react";
import axios from "axios";
import ProductList from "../components/Index/ProductList";
import baseUrl from "../utils/baseUrl";
import { Message, Container } from "semantic-ui-react";

function Home({ products }) {
    const [message, setMessage] = useState(false);
    return (
        <>
            <Container>
                {message ? (
                    <Message
                        deleted
                        icon="checked"
                        color="red"
                        content=" Product Successfully Deleted"
                    />
                ) : (
                    ""
                )}
            </Container>
            <ProductList products={products}></ProductList>
        </>
    );
}

How can I make this setMessagebe callable in ProductAttributes? am I doing it right with the Parent to Child Relation or should I bring the useState in the child to parent?

3 Answers

You can create an handler in the Home Component like this

const handleSetMessage = (message) => {
    setMessage(message)
}

this handler will be responsible of updating the value of message state in the Home component. and this methode you can pass it as props to ProductList component which will also pass it down to ProductAttribute. This will force you to pass props till the lowest level in your APP where you need to call that method.

Or you can take advantage of Context API which will allow you to have access to that method without passing it down as props.

const MessageContext = React.createContext("");

And in the Home component you use that Context like this

function Home () {
    const [message, setMessage] = useState('');
    
    const handleSetMessage = () => {
        setMessage(true)
    }
    return <MessageContext.Provider> value={{setMessage: handleSetMessage}}>
         // The code which render the component child goes here.
    </MessageContext.Provider>
}

After that in your ProductAttribute Component you access to that setMessage function like this

import React, { useContext} from 'react';


const ProductAttribute = (props) => {
    const { setMessage } = useContext(MessageContext);
    
    const handleDelete = async () => {
        // Here you call the setMessage function which will update state in the `Home` Component
        setMessage();
    } 

    return <div>

    </div>
}

Answered by Yves Kipondo on December 7, 2021

Once you show you a message, wait for 5sec to close the message and redirect back to the home directory. just place the route.push('/') inside setTimeout so it will wait for 5sec to be redirected.

async function handleDelete() {
    const url = `${baseUrl}/api/product`;
    const payload = { params: { _id } };
    await axios.delete(url, payload);
    setMessage(true);
    setTimeout(function () {
        router.push("/");
        setMessage(false);
    }, 5000);
}

Answered by Ericgit on December 7, 2021

How can I make this setMessagebe callable in ProductAttributes?

A good practice would encompass you creating a handler function which delegates to the setState function and passing the reference of this function to ProductAttributes as props.

this is an example:

const [counter, setCounter] = useState(0);
const handleIncrementCounter = () => setCounter(counter + 1);
<ChildComponent handleIncrementCounter ={handleIncrementCounter }/>

then in ChildComponent..

function ChildComponent(props) {
   return (
      <button onClick={props.handleIncrementCounter}/>
   );
}

Answered by pixelatedCat on December 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP