【问题标题】:React - state not getting updated after a prop being sent from another componentReact - 从另一个组件发送道具后状态未更新
【发布时间】:2020-05-13 15:48:02
【问题描述】:

我遇到了麻烦

我的BrowseModalUpload 组件中确实有一个弹出窗口,并且我将状态设为

class BrowseModalUpload extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            modalIsOpen: this.props.browseAssetComponent ? this.props.browseAssetComponent : false,
...
}}

所以最初没有弹出窗口,当您单击一个链接时,setState modalIsOpen 为 true 并且模态打开 - 这是正常流程 当我点击关闭窗口时,它 setState modalIsOpen 为假。

所以我只是点击弹出窗口,然后点击关闭按钮,现在我从不同组件中点击这个弹出窗口,将 propbrowseAssetComponent 设置为 true,它没有打开

模态代码是这样的

<Modal transparent isOpen={this.state.modalIsOpen} onAfterOpen={this.afterOpenModal} onRequestClose={this.closeModal} ariaHideApp={false}>

this.state.modalIsOpen 仍然是假的,当我从另一个组件调用它并且这个弹出窗口没有出现时,它不会被更新。

如果你们需要更多信息,请告诉我。 任何帮助都可以解决我的障碍

【问题讨论】:

  • 您是否要还原 this.closeModal 中的布尔值?你能发布整个组件吗?
  • closeModal() { this.setState({ modalIsOpen: false }); } @User965207
  • 到目前为止我同意下面的答案,但为了您的理解,它没有被更新的原因是因为当 React 创建组件时它会调用构造函数。当您将新道具传递给组件时,不会调用构造函数,因为该组件已经实例化。取而代之的是 React.Component 类的 componentDidUpdate 方法是使用先前和当前的道具调用的。
  • @MarioSubotic 那么理想的解决方案是什么
  • 你能在代码沙盒中创建一个最小的可重现示例吗?

标签: reactjs state react-props


【解决方案1】:

不要在 state 中定义你的 props。

最好这样直接通过

<Modal transparent isOpen={this.props.modalIsOpen} onAfterOpen={this.afterOpenModal} onRequestClose={this.closeModal} ariaHideApp={false}>

并像这样处理父组件函数

handleModel=()=>{
  this.setState(prev=>({modalIsOpen:!prev.modalIsOpen}));
}

查看此示例https://codesandbox.io/s/model-popup-o1z0p。希望对你有帮助。

【讨论】:

  • 在很多情况下它依赖于 this.state.modalIsOpen 并且仅来自父级它依赖于 props。所以我们不能总是这样给予。在组件中查看如果我需要打开和关闭,你告诉的解决方案将失败,因为它取决于状态。 `如果控件来自父级,您的条件将起作用
【解决方案2】:

您可以使用 componentDidUpdate 生命周期方法,您可以在其中根据道具设置状态。

    class BrowseModalUpload extends React.Component {
            constructor(props) {
                super(props)
                this.state = {
                    modalIsOpen: this.props.browseAssetComponent ? this.props.browseAssetComponent : false,
        ...
        }
        componentDidUpdate(prevProps){
if(this.prevProps.browseAssetComponent != this.props.browseAssetComponent)
        this.setState ({
                    modalIsOpen: this.props.browseAssetComponent ? this.props.browseAssetComponent : false)
        }}
        }

【讨论】:

  • 这将导致无限循环,除非您添加条件。 reactjs.org/docs/react-component.html#componentdidupdate
  • 你是对的@ssdh233。会导致无限循环
  • @User965207 你能解释一下吗
  • componentDidUpdate LifeCycle 方法将获取 prevProps 作为函数的输入。因此,当您使用新的 Props 更新组件时,我们可以将其与旧的 Props 进行比较,并且仅在值更改时才更新
  • 收到此错误 react-dom.development.js:25621 Uncaught Invariant Violation: 超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。
【解决方案3】:

这样做,

constructor(props) {
  this.state = {
    foo: props.foo
  }
}

你刚刚从一个道具初始化了一个状态。 React 不会为你同步 this.state.foo 和 this.props.foo 的值。

如果你想在 props 改变时改变你的状态,你可以在getDerivedStateFromProps.

static getDerivedStateFromProps(props, state) {
 return { foo: props.foo };
}

但是,如果你仔细阅读the document of getDerivedStateFromProps,你会发现 React 不建议在大多数情况下使用这种方法。从您的代码中,我真的不明白为什么this.props.browseAssetComponent 会影响this.state.modalIsOpen。如果您发布整个代码,我可以提供进一步的建议。

【讨论】:

  • 我给了这样的静态 getDerivedStateFromProps(props, state) { this.setState({ modalIsOpen: props.browseAssetComponent }); } 但它给了我错误无法读取未定义的属性“setState”
  • 为了清楚起见:当您单击关闭模式时,modalIsOpen 的状态设置为 false。现在再次如果我单击以从其他组件打开弹出窗口,我只是发送一个参数说 browseAssetComponent 为 true 并且基于此值我需要将 modalIsOpen 设置为 true ,但它没有发生,因为模态代码就像这样
  • @midhunk 抱歉,我没有仔细检查代码。正确的做法是使用return { modalIsOpen: props.browseAssetComponent } 而不是this.setState({ modalIsOpen: props.browseAssetComponent }
  • 根据您的描述,我建议当您单击以从其他组件打开弹出窗口时,在该 onClick 回调中直接将 modalIsOpen 设置为 true。如果那个“其他组件”与 modal 不在同一级别,而不是将值从 prop 传递到 state,您可以 lift state up like this
  • 我找到了解决方法。我试过你的代码,但它没有显示弹出窗口。我尝试的代码是 componentWillReceiveProps(newProps) { if(newProps && newProps.browseAssetComponent){ this.setState({modalIsOpen: newProps.browseAssetComponent}); } }
猜你喜欢
  • 2020-05-31
  • 2017-10-06
  • 2020-01-16
  • 2020-12-21
  • 2022-01-19
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 2020-12-29
相关资源
最近更新 更多