简体   繁体   English

React - 从外部组件更改 state

[英]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.我知道我会问一个问题,这会破坏有关使用 React 的核心/基本方式的一些规则......但也许通过这个例子,有人可以帮助我解决我面临的问题。

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 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.问题是我需要从父组件的子组件更改 state,但我不想在父组件中运行渲染方法或处理父组件中的 state。

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;具体来说,我需要更改一个孩子(MyFirstChild)的 state,在另一个孩子(SecondChild)读取击键并运行 API 以从我的后端获取一些值之后; after that, I need to send the change to "MyFirstChild" to change his state.之后,我需要将更改发送到“MyFirstChild”以更改他的 state。 The parent component has ~50 child components and I blocked the re-render method (With the method shouldComponentUpdate )父组件有大约 50 个子组件,我阻止了重新渲染方法(使用方法shouldComponentUpdate

The expected answer is: "It's not possible, or, you broke the good use of React"...预期的答案是:“这是不可能的,或者,你破坏了对 React 的良好使用”......

But, maybe using forwardRef or ref, or something else that I not see can help me to work around this...但是,也许使用 forwardRef 或 ref,或者其他我看不到的东西可以帮助我解决这个问题......

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.要从父组件更改子组件的 state 而无需运行渲染方法(在父组件中):一种可能的解决方案是使用 Redux。 With Redux from the parent you can dispatch an Action (execute an Action that changes the state of Redux).使用父级的 Redux 可以调度一个动作(执行一个更改 Redux 的 state 的动作)。 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.在子组件中,您会收到您更改的 state 的那部分(它可能是字符串、object 等)作为道具。 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 https://react-redux.js.org/introduction/basic-tutorial

You could also use Context for the same purpose.您也可以将 Context 用于相同目的。

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.但是,我看到了您的代码示例,我不确定您不想在父级中进行渲染的确切原因,但是您需要的最简单的解决方案是发送您想要执行的 function父母作为道具和标题。

If you want to change things from the parent, without re-rendering again with Redux, it would be something like this:如果你想改变父级的东西,而不用 Redux 重新渲染,它会是这样的:

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.同样,如果您使用 Redux 进行此操作,则可以从 Redux 存储中获取“标题”道具,并且在父级中,您将更改该变量(调用 Z19D8912E22112EB3535C200CC3352 操作)

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.如果您想从子组件触发事件,您可以从子组件调度操作,或者您可以调用 function(您从父组件接收)并在需要时调用 function。

Can't we use props here for passing data instead of trying to manipulate state from outside of component?我们不能在这里使用道具来传递数据,而不是尝试从组件外部操作 state 吗?

Based on @david paley explanation...基于@david paley 的解释...

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.如果实现这一点的唯一方法是使用 Redux,我发布我的解决方案(这是相同的示例,但是,实现 Redux)......希望对其他人有用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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