繁体   English   中英

React - 从外部组件更改 state

[英]React - Change state from external component

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

这不是我项目的完整代码,但准确地展示了我的问题的想法:

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

问题是我需要从父组件的子组件更改 state,但我不想在父组件中运行渲染方法或处理父组件中的 state。

有没有办法做到这一点? 在我的项目中,我有一个创建多个通用子级的父级,处理这个请求会更加困难。

具体来说,我需要更改一个孩子(MyFirstChild)的 state,在另一个孩子(SecondChild)读取击键并运行 API 以从我的后端获取一些值之后; 之后,我需要将更改发送到“MyFirstChild”以更改他的 state。 父组件有大约 50 个子组件,我阻止了重新渲染方法(使用方法shouldComponentUpdate

预期的答案是:“这是不可能的,或者,你破坏了对 React 的良好使用”......

但是,也许使用 forwardRef 或 ref,或者其他我看不到的东西可以帮助我解决这个问题......

要从父组件更改子组件的 state 而无需运行渲染方法(在父组件中):一种可能的解决方案是使用 Redux。 使用父级的 Redux 可以调度一个动作(执行一个更改 Redux 的 state 的动作)。 在子组件中,您会收到您更改的 state 的那部分(它可能是字符串、object 等)作为道具。 因此,当它从父组件更改时,您的子组件将再次渲染,而无需在父组件中运行渲染方法。

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

您也可以将 Context 用于相同目的。

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

如果你想改变父级的东西,而不用 Redux 重新渲染,它会是这样的:

在父

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

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

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

在孩子

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);

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

如果您想从子组件触发事件,您可以从子组件调度操作,或者您可以调用 function(您从父组件接收)并在需要时调用 function。

我们不能在这里使用道具来传递数据,而不是尝试从组件外部操作 state 吗?

基于@david paley 的解释...

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

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