1

Hi I am struggling to get my head around how I return some data from a child to a parent?

I am trying to create components to organise my code.

I have an area that I have extracted that deals with the user selecting if they want to Gift Aid on a donation.

import React, { useState } from 'react';

type Donation = {
  donation: number;
};

export default function GiftAid({ donation }: Donation) {
  const [giftAid, setGiftAid] = useState(false);
  return (
    <section>
      <div className="mt-12 flex items-center flex-col text-center">
        <img src="/images/gift-aid-logo.png" alt="Gift Aid" />
        <h2 className="mt-8 text-4xl font-semibold text-gray-800">
          Are you a UK tax payer?
        </h2>
        <p className="mt-4 text-gray-700">
          Gift Aid is reclaimed by the charity from the tax you pay for the
          current year. Your address is needed to identify you as a current UK
          taxpayer.
        </p>
        <p>
          Boost your donation by&nbsp;
          <strong className="text-gray-800 font-semibold text-lg">
            25%&nbsp;
            {donation > 0 && (
              <span>
                (
                {new Intl.NumberFormat('en-GB', {
                  style: 'currency',
                  currency: 'GBP',
                }).format(donation * 0.25)}
                )&nbsp;
              </span>
            )}
          </strong>
          at no extra cost to you.
        </p>
        <label className="flex flex-col items-center mt-4">
          <input
            type="checkbox"
            className="h-6 w-6 border-2 rounded text-blue-800"
            onClick={() => setGiftAid(!giftAid)}
          />
          <span className="mt-4 text-md font-semibold">
            Please claim Gift Aid on my behalf
          </span>
        </label>
      </div>

      {giftAid && (
        <div className="mt-4 text-gray-400 text-center">
          <p>
            I confirm that this is my own money and I would like The Gerry
            Richardson Trust to treat all the donations I have made in the past
            4 years (if any) and any future donations I make, unless I notify
            you otherwise, as Gift Aid donations.
          </p>
          <p className="mt-2">
            I also confirm that I am a UK taxpayer and understand that if I pay
            less Income Tax and/or Capital Gains Tax in the current tax year
            than the amount of Gift Aid claimed on all my donations it is my
            responsibility to pay any difference.
          </p>
        </div>
      )}
    </section>
  );
}

I am passing the amount of the donation down to the component and it renders the correct calculation advising the user of how much they can add to their contribution. I use this component like this:

<GiftAid donation={donation} />

What I need to know now is if this is true or false.

I have an API that I pass the boolean to so I need to pass the giftAid state back up into the parent component? I just cant seem to figure this out? Any pointers, sites or videos to watch?

Thanks in advance

tuppers
  • 98
  • 2
  • 8
  • where is your child component present in the above code ? – Sakshi Dec 20 '20 at 12:55
  • you can pass any value to your parent, simply by calling a function from your child component to your parent component. write a function in your parent component, then pass it as props to your child component. Then you need to call that function from your child component as this.props.what_ever_your_props_name(the_value_you_want_to_pass_to_props); @tuppers – Amit Chauhan Dec 20 '20 at 12:57
  • calledFromChild = (value) => console.log(value); // write this in your parent component. ------------------> // pass your function as a props to your child component. -----------------> in your child component you can call it >> this.props.calledFunction("this is child value"); // When you called this function in child, it will call the parent function, hence calledFromChild will be execute and "this is child value" will be log in console @tuppers – Amit Chauhan Dec 20 '20 at 13:00
  • You can try and use React context api or define a state in your parent component (which I think you have done already) and then pass it down as props to your child component, now change it from your child component. – Gayatri Dipali Dec 20 '20 at 13:09

6 Answers6

3

You don't pass values from child to parent in React. React is unidirectional - data flows one way - from parent to child.

What you can do is to move given state from child to parent (so that you have one source of truth) and then pass to the child the data it needs as well as a function that allows to change the state in the parent.

marzelin
  • 10,790
  • 2
  • 30
  • 49
1

Thanks for taking the time to look at this :-)

Using the info I have managed to solve this.

I added:

type Donation = {
  donation: number;
  giftaid: boolean;
  handleGiftAid: () => void;
};

export default function GiftAid({
  donation,
  giftaid,
  handleGiftAid,
}: Donation) {

to the top of the function and then used:onClick={() => handleGiftAid()}

I then created the following in my parent component:

const handleGiftAid = () => {
    setGiftAid(!giftAid);
  };

and then used this to pass to the child:

<GiftAid
          handleGiftAid={handleGiftAid}
          donation={donation}
          giftaid={giftAid}
        />

all is working now so thank you!

tuppers
  • 98
  • 2
  • 8
0

you can pass the setGiftAid down to the child component and use that in the child component to set the state.

Bill
  • 512
  • 4
  • 14
0

In react, you can pass data in one direction i.e., parent to child using props, but its not possible here to return any value from the child component to parent component, in your case you can create a varible in state in parent and can modify that state variable using callback function that you need to pass as the props from parent to child to get the updated value from the child.

Find the link for the callback function in react: callback function to update state of parent

0

I use this solution... because I like freedom! It seems to work.

// It seems to work, may may not be legal.
module Text = {
   @react.component
   let make = (~init,~set,~id) => {
     let (text, setText) = React.useState(_ => init);
     set := (text => setText(_ => text))
     <span id>{React.string(text)}</span>
  }
}
0

To get the value of a react child component to the parent component (Got to implement this in Typescript)

    const Parent : React.FC = () => {

   const [maintenanceChecklist, setMaintenanceChecklist] = useState<MaintenanceChecklist | null>();

   const updateMaintenanceChecklist = (maintenanceChecklist:MaintenanceChecklist) => {
    setMaintenanceChecklist(maintenanceChecklist);
  }
 
  return (
    <div>
      <Child 
      data={communitySystemTypesList} 
      handleUpdatedMaintenanceChecklist={updateMaintenanceChecklist} 
    />
    <div className="detailItem">
                          <span className="itemKey">Checklist Name:</span>
                          <span className="itemValue">{maintenanceChecklist?.title}</span>
                        </div>
    </div>
  )
}

//In the child component //creating a props interface for the table components types

interface tableProps {
  data: CommunitySystemTypesList [] | null;
  handleUpdatedMaintenanceChecklist: (checklist: MaintenanceChecklist) => void;
}


const Child : React.FC = () => {
   
const [maintenanceChecklist, setMaintenanceChecklist] = useState<MaintenanceChecklist>();

    useEffect(() => {
        handleUpdatedMaintenanceChecklist(maintenanceChecklist!)
    }, [maintenanceChecklist]);

    const handleViewMaintenanceChecklist = (maintenanceChecklist: MaintenanceChecklist) => {
        setMaintenanceChecklist(maintenanceChecklist);
    };

   return (
     <div>
       <span className="hasAccount">
                      <Button 
                          style={{
                            "fontSize":"10px",
                            "marginTop":"5px", 
                          }}
                          startIcon={<DeleteIcon />}
                          size="small"
                          variant="outlined"
                          color="secondary"
                          onClick={()=> handleViewMaintenanceChecklist(row.maintenanceChecklist)}
                      >
                        View Details
                      </Button>
                    </span>
     </div>
   )
}

This the full code on how you can get the value of a react child component, by implementing a callback function that updates parent component when an value changes in the child component