Antonio Pavicevac-Ortiz
Antonio Pavicevac-Ortiz

Reputation: 7739

React Hooks: Can't send state from Child component to Parent component

I have a <Day/> component which renders a table full of times through the day.

calendar and day component

Right now I have a handleChange function in the <TableLayout/> which is listening for changes in the text-area.

function TableLayout({ sendEventTargetToParent }) {
  var [amountOfRows, setAmountOfRows] = useState(24);
  var [textValue, setTextValue] = useState('');
  var [eventName, setEventName] = useState('');

 useEffect(() => {
   sendDataToParent();
 }, [eventName, textValue]);

  function sendDataToParent() {
    sendEventTargetToParent(eventName, textValue);
  }

  function handleChange(event) {
    var { name, value } = event.target;
    setEventName(name);
    setTextValue(value);
  }

The markup:

  <TextArea
   rows={2}
   name="textarea"
   value={textValue}
   onChange={(e) => handleChange(e)}
   placeholder="Tell us more"
  />

I'd like to send that info from the text-area to the component, you probably noticed already noticed the prop TableLayout is consuming:

 function TableLayout({ sendEventTargetToParent }) {

Which I thought belongs in useEffect because it's creating a side-effect:

useEffect(() => {
  sendDataToParent();
}, [eventName, textValue]);

function sendDataToParent() {
  sendEventTargetToParent(eventName, textValue);
}

Anyway the idea is when those local variables/state change in TableLayout it gets kicked up to Day...

export default function Day({ dayInfo }) {
  var [dayInfoInChild, setDayInfoInChild] = useState({});
  var [currentDate, setCurrentDate] = useState('');
  var [timeOfDay, setTimeOfDay] = useState('');
  var [eventNameFromChild, setEventNameFromChild] = useState('');
  var [textValueFromChild, setTextValueFromChild] = useState('');

  function getEventTargetFromChild(eventName, textValue) {
    setEventNameFromChild(eventName);
    setTextValueFromChild(textValue);
  }

    useEffect(() => {
      if (dayInfo !== null) {
        var modifiedDayInfo = dayInfo
         .split(' ')
         .map((item) => {
           if (item.indexOf(',')) return item.replace(/,/g, '');
        })
         .join('-');

         setCurrentDate(modifiedDayInfo);

         if (localStorage.getItem(modifiedDayInfo)) {
           var stringVersionOfModifiedDayInfo = modifiedDayInfo;

           modifiedDayInfo = JSON.parse(localStorage.getItem(modifiedDayInfo));

         if (!dayInfoInChild.hasOwnProperty(stringVersionOfModifiedDayInfo)) {
          setDayInfoInChild({
            ...dayInfoInChild,
            [stringVersionOfModifiedDayInfo]: modifiedDayInfo,
          });
        }

      } else {
        localStorage.setItem(modifiedDayInfo, JSON.stringify({}));
      }
        if (dayInfoInChild.hasOwnProperty(currentDate)) {
          setDayInfoInChild({
            ...dayInfoInChild,
            [currentDate]: {
              [eventNameFromChild]: textValueFromChild,
            },
          });
        }
      }
    }, []);

And the code in the Day'suseEffectessentially creates an JSON object in localstorage with its key based on the date if needed if not it pulls that key and object converts it to a JS object and puts it into the state usinguseState`.

  var [eventNameFromChild, setEventNameFromChild] = useState('');
  var [textValueFromChild, setTextValueFromChild] = useState('');

  function getEventTargetFromChild(eventName, textValue) {
    setEventNameFromChild(eventName);
    setTextValueFromChild(textValue);
  }

this is the part where the state from the Child gets set in Day.

   if (dayInfoInChild.hasOwnProperty(currentDate)) {
     setDayInfoInChild({
       ...dayInfoInChild,
         [currentDate]: {
           [eventNameFromChild]: textValueFromChild,
         },
     });
  }

But right now I able to add one key stroke into the object and then the UI locks:

enter image description here

So how can I create a cohesive flow from my Child to the Parent using hooks?

Upvotes: 0

Views: 151

Answers (1)

Furqan Aziz
Furqan Aziz

Reputation: 1104

By understanding your problem i suggest you to use useContext

Here is a link which can help you to solve this problem.

https://vimalselvam.com/post/react-hooks-lift-up-pass-down-state-using-usecontext-and-usereducer/

Upvotes: 2

Related Questions