如何在没有Redux的情况下从任何地方更改组件的状态?

时间:2018-08-25 18:22:02

标签: reactjs

这是不好的做法吗?

  1. 组件的导出状态更改功能
  2. 从其他文件导入。
  3. 调用函数以更改状态?

这样,我们可以从任何地方更改某些组件状态。

例如...

我们想在任何地方更改Model.js状态。

Modal.js

import React from 'react';

export let toggleModal;

export default class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false,
    };
    toggleModal = this.toggleModal;
  }

  toggleModal = () => {
    this.setState({ open: !this.state.open });
  };

  render() {
    const { open } = this.state;
    return <div style={{ color: 'red' }}>{open && 'Hello Modal'}</div>;
  }
}

App.js(某些顶级组件)

import React from 'react';
import Modal from './Modal';

export default () => (
    <>
        ...
        <Modal />
        ...
    </>
);

Somewhere.js

import React from 'react';
import {toggleModal} from './Modal';

export default () => (
    <>
        <h1>Hello!</h1>
        <button onClick={() => toggleModal()}>open Modal!</button>
    </>
);

但是React官方文档中没有参考,这是不好的做法吗?

React Docs的建议...

  1. 只需传递函数道具即可将父状态从父状态更改为子状态
  2. 使用上下文
  3. Redux或Mobx

但是,这些对我来说太复杂了。

此处的示例代码
https://next.plnkr.co/edit/37nutSDTWp8GGv2r?preview

5 个答案:

答案 0 :(得分:0)

<Modal />是子组件。因此,要在子组件中调用函数,您只需使用Ref。 您可以参考this page以获得有关参考的更多信息。

您可以为该子代分配一个类变量作为引用,并将该类变量用作对象来调用其函数。

答案 1 :(得分:0)

一切在开始时似乎都是不堪重负且困难重重。但是随着我们对它们的掌握,这使我们有更多的信心去挖掘。 我建议使用redux,这是我们解决道具钻孔问题的方法。您可以调度一个动作并将reducer连接到相应的组件,该组件在更新状态时将重新呈现。我向大多数人推荐以下示例,以真实的例子来学习redux的故事: Understanding Redux: The World’s Easiest Guide to Beginning Redux

除此之外,您还可以参加图书馆的作者 Dan Abramov ,该课程是egghead.io上的免费redux课程: Getting Started with Redux

答案 2 :(得分:0)

几乎像您的代码示例一样,您遇到的问题是:

它将不起作用:您的toggleModal()方法期望this引用实际的组件实例。当onClick()处理函数触发时,您将toggleModal()作为普通函数调用。 this上下文将是错误的,因此在最佳状态(在您的示例中)会出现错误,因为您尝试调用undefined,在最糟糕的情况下 < / em>(通常)会导致您调用了错误的方法。

考虑它时,对于任何非平凡的React组件,您将很难获得对当前正在使用的实际实例的引用:您必须确保您不要忘记在上调用该方法。正确的组件实例,并且您还必须考虑可以出于任何原因“随意”创建/销毁实例。例如:如果您的组件是作为其他组件的render()方法的一部分间接呈现的,该怎么办?像这样的多层间接操作使它变得更加困难。

现在,您可以通过放弃ref而放弃所有操作,但您会发现现在必须跟踪哪个引用引用了什么特定实例,如果您在一棵渲染树中碰巧要考虑多个组件...

答案 3 :(得分:0)

每当您认为一个组件需要处理其兄弟状态时,解决方案通常是将状态提升一级。

export default class Modal extends React.Component {
  render() {
    const { isOpen } = this.props;
    return <div style={{ color: 'red' }}>{isOpen && 'Hello Modal'}</div>;
  }
}


export default class Home {
    this.state = {
      isOpen: false,
    };
    toggleModal = () => {
      this.setState({ isOpen: !this.state.isOpen });
    }

    render() {
      const { isOpen } = this.state;
      return (
        <>
        <h1>Hello {name}!</h1>
        <button onClick={() => this.toggleModal()}>open Modal!</button>
        <Modal isOpen={isOpen}/>
        <p>Start editing and see your changes reflected here immediately!</p>
        </>
      )
    }
}

这样,Home可以处理状态并解决您的问题。 如果需要将状态“深入”给孩子,这可能会很烦人,这是redux或react-context可以解决的问题。

答案 4 :(得分:0)

我发现在特殊情况下,我的方法是

特殊情况意味着类似于customAlert组件。

可以一次在App中安装一个customAlert组件实例。

要实现这一目标...

1。使用@font-face { font-family:'american'; src:url('American Typewriter.ttf') format('truetype');} @font-face { font-family:'bdmod'; src:url('BASKVILL.TTF') format('truetype');} @font-face { font-family:'brush'; src:url('BRUSHSCI.TTF') format('truetype');} #american{font-family:'american';} #bdmod{font-family: 'bdmod';} #brush{font-family: 'brush';} 访问和更改DOM
2.将状态更改功能或组件附加到ref并调用window
3.我的情况:导出状态更改功能并从其他文件导入。

这是如何处理react Context https://next.plnkr.co/edit/EpLm1Bq3ASiWECoE?preview