你可以在 React 组件的 return 函数中设置外部 HTML 吗?

can you set outer HTML in return function of a React component?

MailchimpSubscribe 组件的默认行为会在用户注册时显示状态警报。我想将此状态警报移出它在 DOM 中的位置,以便它显示在页面顶部。

我的代码如下所示:

import MailchimpSubscribe from "react-mailchimp-subscribe"
import SimpleForm from './SimpleForm.js'

function Info() {
 return (
  <div className="canary">
   <MailchimpSubscribe url={process.env.REACT_APP_MAILCHIMP_URL} 
    render={({subscribe, status, message}) => <SimpleForm
     status={status}
     message={message}
     className="form"
     style={{}}
     onSubmitted={formData => subscribe(formData)}
    />
   }/>
  </div>
 );
}

export default Info;

要更改默认按钮文本,我创建了自己的 SimpleForm.js 组件:

import React from "react";

// a basic form
const SimpleForm = ({ status, message, className, style, onSubmitted }) => {
  let input;
  const submit = () =>
    input &&
    input.value.indexOf("@") > -1 &&
    onSubmitted({
      EMAIL: input.value
    });

  return (
    <div className={className} style={style}>
      {status === "sending" && <div style={{ color: "blue" }}>sending...</div>}
      {status === "error" && (
        <div
          style={{ color: "red" }}
          dangerouslySetInnerHTML={{ __html: message }}
        />
      )}
      {status === "success" && (
        <div
          style={{ color: "green" }}
          dangerouslySetInnerHTML={{ __html: message }}
        />
      )}
      <input
        ref={node => (input = node)}
        type="email"
        placeholder="Your email"
      />
      <button onClick={submit}>Subscribe</button>
    </div>
  );
};

export default SimpleForm;

我如何修改此 return 函数,以便 dangerouslySetInnerHTML={{ __html: message }} 部分设置在 <div className="canary"> 上?

From what I see in component definition you can pass render props

MailchimpSubscribe.defaultProps = {
  render: ({ subscribe, status, message }) => (
    <SimpleForm
      status={status}
      message={message}
      onSubmitted={formData => subscribe(formData)}
    />
  )
};

SimpleForm 并包括特定的 className style

<MailchimpSubscribe url={process.env.REACT_APP_MAILCHIMP_URL} 
  render={({subscribe, status, message}) => <SimpleForm
      status={status}
      message={message}
      className="form"
      style={{}}
      onSubmitted={formData => subscribe(formData)}
    />
}/>

如果您需要更多自定义,您可以根据内部内容创建自己的组件 SimpleForm

我是这样理解这个问题的:

问题

如何在 Component B 内渲染作为道具传递给 Component A 的数据?

  • MailchimpSubscribe 在其内部状态中保存 message 并将其作为 prop 传递给其 render 函数
  • 的结果

回答

React 旨在仅以单向数据流将数据从父级传递给子级, 因此作为道具传递给 MailchimpSubscribe 的数据不能直接在另一个不是其子组件的组件中呈现

我能想到的避免这种情况的最佳方法是利用 Context API 在 MailchimpSubscribe 内呈现的 SimpleFormSimpleForm 之间创建共享状态=18=] 在您应用的其他地方呈现。

  • 在新文件中SharedState.js
    • 创建 SharedContext 以允许组件访问上下文
    • 创建 SharedProvider 父对象,使其所有子对象都可以使用上下文
  • SimpleForm
    • 阅读SharedContext
    • 设置效果以将 statusmessage 值推送到上下文。每次这些值更改时都会调用此效果。
    • return nullstatus 不为空时,因为您想在其他地方呈现 message 并隐藏表单。
  • DisplayMessage
    • 阅读SharedContext
    • 使用 SharedContext 中的 statusmessage 来呈现您的消息

演示

我把 this CodeSandbox 放在一起说明了这个策略。

参考资料

希望对您有所帮助!让我知道您是否需要进一步澄清