【问题标题】:React.js "global" component that can be created multiple times可以多次创建的 React.js “全局”组件
【发布时间】:2018-08-31 08:27:52
【问题描述】:

我无法理解这一点。

问题:假设有一个应用程序,我想从我的代码中创建某种通知/对话框/等。

我可以拥有“全局”组件并对其进行管理,但它会限制我一次只能接收一个通知,这不适合。

render() {
  <App>
    // Some components...
    <Notification />
  </App>
}

或者我可以通过组件Notification 本身管理多个通知。但是状态管理会不清楚。

另一个问题,如果我从该组件获得某种用户确认(如果它是确认对话框而不是简单通知),则使用此解决方案处理起来不是很方便。

另一种解决方案是手动渲染组件。比如:

notify(props) {
  const wrapper = document.body.appendChild(document.createElement('div'))
  const component = ReactDOM.render(React.createElement(Notification, props), wrapper)
  //...
  // return Promise or component itself
}

所以我会这样称呼:

notify({message: '...'})
  .then(...)

或:

notify({message: '...', onConfirm: ...})

这个解决方案看起来很老套,我想让 React 处理渲染,而且我还有一个额外的不必要的 div。此外,如果 React API 发生变化,我的代码也会中断。

这种情况的最佳做法是什么?也许我错过了一些完全不同的东西?

【问题讨论】:

  • 抱歉,您的问题似乎不清楚。
  • 你使用什么样的状态管理?这类问题就是为什么要发明 Redux 等工具的原因。组件可以将数据传递到共享数据存储,而无需了解使用该数据的其他组件。解耦组件逻辑使大型应用程序更易于维护。
  • @HåkenLid 你需要为此引入 redux 吗?似乎 React Context 在这里可以完美运行。
  • 目前还没有状态管理。但似乎这个问题并没有通过状态管理来解决(或者我只是不明白一个好方法)。因此,例如,用户试图删除一些与组件相关的数据,我应该要求确认。所以我将挂起的“删除请求”传递给状态,然后其他一些组件获取它,管理“确定”按钮并传递已解决的“删除请求”,初始组件获取此状态并正确呈现?对我来说似乎不是很清楚。
  • @CameronDowner 这是一个非常中肯的评论,包括我在内的很多人默认不会想到 Context API,我认为在很多情况下 redux 工作流可以被一个简单的上下文 API 使用情况。

标签: javascript reactjs


【解决方案1】:

您可以为此使用React Context

您在应用程序的高级别创建 React 上下文,然后将值关联到它。这应该允许组件创建通知/与通知交互。

export const NotificationContext = React.createContext({
  notifications: [],
  createNotification: () => {}
});

class App extends Component {
  constructor() {
    super();

    this.state = {
      notifications: []
    };

    this.createNotification = this.createNotification.bind(this);
  }

  createNotification(body) {
    this.setState(prevState => ({
      notifications: [body, ...prevState.notifications]
    }));
  }

  render() {
    const { notifications } = this.state;

    const contextValue = {
      notifications,
      createNotification: this.createNotification
    };
    return (
      <NotificationContext.Provider value={contextValue}>
        <NotificationButton />
        {notifications.map(notification => (
          <Notification body={notification} />
        ))}
      </NotificationContext.Provider>
    );
  }
}

通知存储在一个数组中,以便一次允许多个通知。目前,此实现永远不会删除它们,但可以添加此功能。

要创建通知,您将在应用程序中使用相应的上下文使用者。为了演示,我在这里添加了一个简单的实现。

import { NotificationContext } from "./App.jsx";

const NotificationButton = () => (
  <NotificationContext.Consumer>
    {({ notifications, createNotification }) => (
      <button onClick={() => createNotification(notifications.length)}>
        Add Notification
      </button>
    )}
  </NotificationContext.Consumer>
);

You can view the working example here.

【讨论】:

  • 这对于简单的通知来说非常有用。但是如果我想要用户输入怎么办?我需要去 Redux 吗?
  • @UnstableFractal 不,你不需要 Redux。您只需将用户输入传递给createNotification 函数。
  • 我的意思是当它是一个带有通知确认的模态对话框时。例如,当我等待用户输入以发送获取请求时。
  • 我认为这取决于请求的性质。如果你需要另一个组件中请求的状态或响应,我会在那时介绍 Redux。
猜你喜欢
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2022-06-22
  • 2017-08-20
  • 2016-12-15
  • 2018-05-20
  • 1970-01-01
相关资源
最近更新 更多