How to expose the son’s Tates to the father?

Asked

Viewed 72 times

0

Good afternoon!

I would like to know how to solve this problem.

I have a child component that’s like a menu. It contains buttons and currently - according to the click on the functions that are in the parent component - will display other components. I just don’t want the functions below to be in the parent component. I would like such functions to be in the child.

Function:

 const onChangeActive = (event, value) => {
            setSelectionActive(value)
          }

const onChangeType = (event, value) => {
            setChartType(value)
}

But if I put in the child I lose access to the Tates and their changes I need in the father. The Tates are: chartType and the selectionActive. So, I need his states - which in this case are chartType and the selectionActive - accessible in the Parent component.

Component Filho:

const Filho ={type, buttonActive, onChangeType = () => { }, onChangeActive = () => { } ) =>{
    
    return(
    <ToggleButton value={type} onChange={onChangeType}>
      <Button disabled={buttonActive===TABLE}>button 1</Button>
      <Button disabled={buttonActive===TABLE}>button 2</Button>
    </ToggleButton>
    <ToggleButton value={buttonActive} onChange={onChangeActive}>
      <IconButton>
        <Span title="chart" />
      </IconButton>
      <IconButton>
        <Span title="table" />
      </IconButton>
    </ToggleButton>
    )}

Component Pai:

         const Pai = () => {
           const [chartType, setChartType] = useState(1)
           const [selectionActive, setSelectionActive] = useState(1)
    
           const onChangeActive = (event, value) => {
            setSelectionActive(value)
          }
        
          const onChangeType = (event, value) => {
            setChartType(value)
          }
            
            return(
                  <Filho buttonActive={selectionActive}
                  onChangeType={onChangeType}
                  onChangeActive={onChangeActive} />
          {selectionActive === SELECT_CHART ? renderOpcao1() : renderOpcao2()}
           )
        
        }

How I can take these functions onChangeActive and onChangeType of the father, leave in the son but in the father continue with access to the States chartType and selectionActive in the parent component?

  • 1

    You’ve already read the section Elevating the State of the React documentation? There is a relatively detailed explanation that can help you. :)

  • worked, thanks !!

1 answer

0

You can use the React context API. The flow of information from React always goes from top to bottom, from parent to child. To provide a state to several components, from the API context, you must create it in a high hierarchy. Got confused right? Let’s go in pieces then.

  1. The first step is to create a context component, where we will declare methods and provide values that will be accessible globally:

We import the createContext and the useState, which is used by the methods you posted in the question, we create a context, a priori empty, and then export it by default:

import { createContext, useState } from 'react';
const MyContext = createContext({});
export default MyContext;
  1. Great! We already have the context created, but there is one detail missing. Every context needs a preview. It is he who will deliver the information to all his children. A context without a Provider is like a letter without a postman, so we will create it:

Provider is like any functional component of React. We will program the desired methods and return them from jsx:

export function MyProvider({children}) {
   const [chartType, setChartType] = useState(1)
   const [selectionActive, setSelectionActive] = useState(1)
   
   const onChangeActive = (event, value) => {
        setSelectionActive(value)
   }
    
   const onChangeType = (event, value) => {
        setChartType(value)
   }

    return (
        <MyContext.Provider value={{
                chartType,
                selectionActive,
                onChangeActive,
                onChangeType
            }}>
            {children}
        </MyContext.Provider>
    )
}

What we did above was simply transfer the methods and variables of their components to another and return them within the prop value de <Mycontext.Provider />. Having done this, we will now be able to access this information from all the child components of this product. Then consider your components <Filho /> and <Pai />, we need to ensure that they are the children of the President. For this we import the MyProvider:

import { MyProvider } from './caminho/relativo/myContext.js';

function index() {
    return (
        <MyProvider>
            <Pai>
                <Filho />
            </Pai>
        </MyProvider
    )
}

Having done so, all information returned within the value of the Provider will be accessible, but to pull them we need to use the hook useContext(). Let’s assume that inside the child component you want to access the method onChangeActive, for this you would first import the hook and the context:

import { useContext } from 'react';
import MyContext from './caminho/relativo/myContext.js';

Then, inside the component that wants to access the data, we would do:

const { onChangeActive } = useContext(MyContext);

If we wanted to, besides onChangeActive, the state of chartType:

const { onChangeActive, chartType } = useContext(MyContext);

It is important to mention that every time a state is changed within the context, all components that use that context will be rendered again, so make sure that the provider only have children who really need that information. I recommend still that reading from the React documentation itself, which provides complete information on the information flow and lifecycle of the API context. You can see the development of a context from scratch with that video, that despite being done in Act Active, can be completely reused by Act.

  • 1

    If the function has q be shared between father and son context comes to kill ant with bazooka, do not think?

  • It is! Be advised to whom it may concern. The solution you recommended in the comments of the question seems to be much more appropriate, a simple solution to a simple problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.