Can change an object(element) in an external component?

Viewed 68

I want change area (element) when i call changeArea method on another component.

I want to like do this.

First, App.js

export default function App(props) {
    const [area, setArea] = React.useState(<><Button/><Button/></>)

    const changeArea = (element) => {
        setArea(element);
    }

    return (
        <div>
            {<area/>}
            <ChildApp changeArea={changeArea}/>
        </div>
    );
}

And, ChildApp.js

export default function ChildApp(props) {

    // I want do call to change the area.
    props.changeArea(<></Select></>);
    …
}

Anyway this code is not working.

Error

Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

PS. It’s a simplification of the way I want to do it.

2 Answers
const ChildApp = (props) => {
  const buttonHandler = () => {
    props.changeArea(<h1>World</h1>)
  }
  return <><button onClick={buttonHandler}>Hello</button> </>
}

export default function App() {
  const [area, setArea] = React.useState(<><h1>Hello</h1></>)
    const changeArea = (element) => {
        setArea(element);
    }
    return (
        <div>
            {area}
            <ChildApp changeArea={changeArea}/>
        </div>
    );
}

Since you are calling props.changeArea(<></Select></>); in the body of your component, so every time your component renders(function calls) you set the state of parent(App), every update state in component cause to re-render(recall) the component and it's children, as a result you dealing with a loop, you props.changeArea(<></Select></>);, it cause to re-render it's parent, and re-render the parent cause to call props.changeArea(<></Select></>); You must not call in the body of your function directly, you can do it in useEffect or in some eventHandler. like this:

export default function ChildApp(props) {
  ...
  useEffect(()=> {
  props.changeArea(<></Select></>);
  }, []);
  ...
}

In the above code, props.changeArea(<></Select></>); calls first time ChildApp renders and in the other renders of ChildApp it never calls props.changeArea.

If you are looking to understand how you can do it in eventHandler you cand take a look to @Akhil solution.

Related