简体   繁体   中英

React - Change state from external component

I know that I will ask a question that brake some rules about the core/basic way to use React... but maybe with this example, someone helps me to solve the problem that I facing.

This is not the full code of my project, but show exactly the idea of my problem:

https://codesandbox.io/s/change-state-from-external-component-zi79e

The thing is I need to change a state from a child component from the parent component, but I don't want to run a render method in my parent or handle the state in the parent component.

Exists a way to achieve this? In my project, I have a parent that creates multiple generic children and it will be more difficult to handle this request.

And specifically, I need to change the state of one child (MyFirstChild), after another child (SecondChild) read the keystroke and run an API to get some values from my backend; after that, I need to send the change to "MyFirstChild" to change his state. The parent component has ~50 child components and I blocked the re-render method (With the method shouldComponentUpdate )

The expected answer is: "It's not possible, or, you broke the good use of React"...

But, maybe using forwardRef or ref, or something else that I not see can help me to work around this...

To change the state of a child component from the parent without having to run a render method (in the parent): one possible solution would be to use Redux. With Redux from the parent you can dispatch an Action (execute an Action that changes the state of Redux). And in the child component, you receive that part of the state that you change (it could be a string, object, etc) as a prop. So when it is changed from the parent, your child component will render again without having to run a render method in the parent.

https://react-redux.js.org/introduction/basic-tutorial

You could also use Context for the same purpose.

However, I saw your code example, I am not sure the exact reason of why you don't want to make a render in the parent, but the easiest solution for what you need would be to send the function that you want to execute in the parent as a prop and also the title.

If you want to change things from the parent, without re-rendering again with Redux, it would be something like this:

In the parent

const changeTitle = (newTitle) => {
  this.props.setTitle(newTitle);
}

return (
<div className="App">
  <ChildComponent />
</div>
);

const mapDispatchToProps = dispatch => ({
  setTitle: newTitle => dispatch(setTitleACTION(newTitle)),
});

In the child

return (
      <div>
        <h1>
          {this.props.title}
        </h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    );

const mapStateToProps = ({ title }) => ({
  title,
});

export default connect(mapStateToProps, null)(ChildComponent);

Again if you make this with Redux, you can get the "title" prop from the Redux store , and in the parent, you will change that variable (calling to a Redux action) without rendering the parent again.

If you want to fire the event from the child component, you can dispatch the action from the child component or you could call a function (that you receive from props from the parent) and call that function whenever you need.

Can't we use props here for passing data instead of trying to manipulate state from outside of component?

Based on @david paley explanation...

If the only way to achieve this is using Redux, I post my solution (It's the same example, but, implementing Redux)... hope that works for anyone else.

https://codesandbox.io/s/change-state-from-external-component-redux-rmzes?file=/src/App.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM