Search code examples
reactjsjsxreact-props

Change parent's state using child arrow functions, React


I have tried researching but I am having trouble implementing the answers that Ive found. 1) the examples usually use the same onClick example and 2) they uusually use classes unstead of arrow functions, which I am attempting to use.

I am building a tesseract app in which the parent component runs tesseract. I am then trying to send it to a child which turns the raw parent tesseract data into something readable, in this case I map to an array and display it as a JSX component in the parent. That works, but where I am having trouble is I want to also pass upwards and save that array in the parent component state with useState() so I can do additional work later like sending to Mongo or additional analysis by sending it back to other child components using buttons.

So in essence, how do I pass the the array into the parent's state?

Thank you for any help!

--Parent--

const TesseractApp = () => {
  const [tessState, setTessState] = useState();

  const runTesseract = async (tessState) => {
    //read image
    await Tesseract.recognize(require("../images/short.png"), "eng", {
      logger: (m) => console.log(m),
    })
      //return image scanning results and then setTessState
      .then((tess) => {
        setTessState(tess);
      });
  };
  const someFunction = () => {};
  const sendToMongo = () => {};

  if (!tessState) {
    return (
      <div>
        <button className="ui button" onClick={runTesseract}>
          Run Tesseract
        </button>
      </div>
    );
  } else {
    return (
      <div>
        <div>
          <ScanForData tessValues={tessState} />
        </div>
        <button className="ui button" onClick={someFunction}>
          Run Function
        </button>
        <button className="ui button" onClick={sendToMongo}>
          sendToMongo
        </button>
      </div>
    );
  }
};
export default TesseractApp;

--Child--

const ScanForData = (pData) => {
  let allPoints = [];

  const paras = pData.tessValues.data.paragraphs.forEach((para) => {
    allPoints.push(para.text);
  });
  return <div>{allPoints}</div>;
};
export default ScanForData;

Solution

  • In parent:

    const youNameOfCallback = (array) => {
      setTessState(array)
    }
    
    <ChildComponent youNameOfCallback={youNameOfCallback} />
    

    In child:

    useEffect(() => {
      props.youNameOfCallback(YouArrayFromChild)
    }, [])
    
    

    This will be apply when child will be mounted.