Home > front end >  How to use state in great grand parent in react
How to use state in great grand parent in react

Time:12-09

What is the easiest way to set state from 4 components below the first component?

  • First {name}
  • Second
  • Third
  • Fourth {setName}

In fourth component I want to set name and then use it in the first component to render the name like {name}

const First = () => {
  const [name, setName] = useState();
<div>
  <div>{name}
  <Second />
</div>
}

const Second = () => {
 <div>
  <Third />
 </div>
}

const Third = () => {
 <div>
  <Fourth />
 </div>
}

const Fourth = () => {
 <div>
  <div onClick={()=>setName(something.name)}>{something.name). 
  </div>
 </div>
}

CodePudding user response:

In the fourth component you can have a handleNameChange(newName) prop to lift the state up.

const FourthComponent = (
  name: string,
  handleNameChanged: (newName: string) => void
) = {
  const onNameChanged = (newName: string) => handleNameChanged(newName)
}

Same in third and second components to lift up in the same way.

Finally, in the first one you will have something like :

const FirstComponent = () => {
  const [name, setName] = useState<string>('')

  <SecondComponent
    name={name}
    handleNameChange={(name) => setNAme(name)}
  />
}

CodePudding user response:

In a case you want to pass a variable to a parent, you just pass it via a prop function:

const Parent = () => {
    const [var, setVar] = useState();

    useEffect(() => {
        console.log(`${var} in parent`);

    return (
        <Child passVarToParent={setVar} />
    );
}

const Child = (props) => {
    return (
        <input /* ... */ onChange={(e) => props.passVarToParent(e.target.value)} />
    );
}

However, in case of parent-child-chaining, I'd go with some state management like Redux, MobX or React Context.

CodePudding user response:

You can do this by passing setName as a prop from the First component to the Fourth

const First = () => {
  const [name, setName] = useState();
  return (
    <div>
      {name}
      <Second setFirstName={(name) => setName(name)} />
    </div>
  );
}

const Second = ({ setFirstName }) => {
  return (
   <div>
     <Third setFirstName={setFirstName}/>
   </div>)
}

const Third = ({ setFirstName }) => {
 return (
  <div>
    <Fourth setFirstName={setFirstName}/>
  </div>
 )
}

const Fourth = ({ setFirstName }) => {
 return (
   <div>
     <div onClick={() => setFirstName('Test Name')}>Press to set Name</div>
   </div>
 )
}

CodePudding user response:

There is a subject between state sharing among parent and child (I mean props and emit) and state management (as redux). This subject is called Event Bus. There is an example of your code managing data with Event Bus:

const eventBus = {
  on(event, callback) {
    document.addEventListener(event, (e) => callback(e.detail));
  },
  dispatch(event, data) {
    document.dispatchEvent(new CustomEvent(event, { detail: data }));
  },
  remove(event, callback) {
    document.removeEventListener(event, callback);
  },
};
class First extends React.Component {
  constructor(props) {
    super(props);
    this.state = {      
      name: "",    
    };  
  }
  componentDidMount() {
    eventBus.on("name", (data) =>
      this.setState({ name: data.name })
    );
  }
  componentWillUnmount() {
    eventBus.remove("name");
  }
return (<div>
          <div>{name}
          <Second />
        </div>)
}
const Second = () => {
 <div>  
   <Third />
 </div>}
const Third = () => {
  <div>  
    <Fourth /> 
  </div>
}
const Forth = () => { 
  <div>
    <div onClick={()=>eventBus.dispatch("name", { name: "name changed" });}>{something.name). 
    </div>
  </div>
}
  • Related