4

我目前遇到了 Gravity Forms 和 ReactJS 的问题。我正在尝试将重力表单作为模式加载到 ReactJS 组件中以用于联系目的。基本上,我目前的设置方式是GETWP-API加载了表单的页面开始,然后使用dangerouslySetInnerHTML在组件中构建页面。问题是,当我尝试提交表单时,它给我带来了POST. 它试图将其提交URLGET. 我可以在这里使用一些认真的帮助来了解最佳方法。

import React, { PropTypes } from 'react';
import Modal from 'react-modal';
import $ from 'jquery';

class RequestContactModal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      content: ''
    };
  }

  componentWillMount() {
    const wpApiUrl = '../wp-json/wp/v2/pages/61';

    $.ajax({
      url: wpApiUrl,
      type: 'GET'
    })
      .done((response) => {
        console.log(response);
        this.setState({
          content: response.content.rendered
        });
      })
      .fail((response) => {
        console.log('fail');
        console.log(response);
      });
  }

  handleSubmit = (ev) => {
    ev.preventDefault();
    this.props.closeModal();
  }

  handleCloseClick = (ev) => {
    ev.preventDefault();
    this.props.closeModal();
  }

  render() {
    const customStyles = {
      overlay: {
        backgroundColor: 'rgba(0, 0, 0, 0.65)'
      },
      content: {
        top: '50%',
        left: '50%',
        right: 'auto',
        bottom: 'auto',
        marginRight: '-50%',
        transform: 'translate(-50%, -50%)',
        background: '#fff'
      }
    };

    return (
      <Modal
        isOpen={this.props.isOpen}
        onRequestClose={this.props.closeModal}
        style={customStyles}
      >
        <div>
          <p>Gravity Forms</p>
          <div dangerouslySetInnerHTML={{__html: this.state.content}} />
        </div>
      </Modal>
    );
  }
}

RequestContactModal.propTypes = {
  closeModal: PropTypes.func.isRequired,
  isOpen: PropTypes.bool
};

RequestContactModal.defaultProps = {
  isOpen: false
};

export default RequestContactModal;
4

1 回答 1

0

这个问题可能已经过时了,但是使用 WP REST API 在 WordPress 上“不露面”地构建 React 应用程序正在以巨大的方式获得动力(它甚至是 WordPress 核心的未来),所以这个问题肯定会越来越多。

所以发生的事情是 Gravity Forms 设置它的表单操作,通过$action = remove_query_arg( 'gf_token' );它依次调用add_query_arg()然后调用$uri = $_SERVER['REQUEST_URI'];- 这意味着当您使用 React 显示包含重力表单的 WordPress 内容时,表单的操作设置为调用的 REST 端点,而不是内容的永久链接。哎呀!

尽管 Gravity Forms 有一个真正的 WP REST API 插件在工作中,但到目前为止我已经能够提出两个可靠的选择:

选项 1 - 完全无头

确保您有一个接受 POST 的 REST 路由(我建议仅重用 GET 路由)并添加do_action('wp');到您的路由回调中。如果你愿意,你可以提前添加它,比如rest_api_init钩子。这将确保在向其发送 REST 请求时触发 Gravity Forms。

或者,您可以GFForms::maybe_process_form()从路由回调中调用或将其用作rest_api_init挂钩中的回调。诀窍是确保在 API 收到请求时调用该方法。

接下来,让 React 处理您的表单提交(您不希望浏览器实际直接发布它并显示您的访问者 JSON)。REST API 将自动返回带有正确处理的重力表单标记的响应...验证/错误消息、确认等。请注意,对于这种方法,重力表单需要 ajax=false。

选项 2 - 不露面(半无头)

假设您想保留 WordPress 的永久链接,您可能会将 REST API 端点配置为匹配 WordPress 永久链接 URI;所以,例如/wp-json/your-post-name-here/等价于/your-post-name-here/。如果没有,您始终可以确保将 URI 与您的请求一起发送。如果这是您处理它的方式,您可以在rest_api_init钩子中添加以下内容:

function tweak_request_uri() {
    $prefix = '/' . rest_get_url_prefix();
    $_SERVER['REQUEST_URI'] = str_replace( $prefix, '', $_SERVER['REQUEST_URI'] );
}

这可确保 REQUEST_URI 与当前页面匹配,以便重力表单能够成功地将其数据发布到 WordPress。然而,虽然这允许 Gravity Forms 回发实际到达服务器,但如果您只使用 REST API,您将不会得到任何有意义的回复......因为响应与对服务器的请求相关联,但 React 是向 API 发出新的、单独的内容请求。因此,你会得到一个新的形式。不好的用户体验,那个。

要解决此问题,您需要在 rest_ensure_response( $data ) 之前使用用于打包数据的任何函数、类、对象等,并从wp_head()挂钩中调用它。您想要 json_encode() 数据并将其作为 Javascript 变量在脚本标记中输出。例如,像这样:

var $react_first_load_data = json_encode( [ 'id' => get_the_id(), 'title' => get_the_title(), 'content' => get_the_content() ] );
printf('<script type="text/javascript">window.reactFirstLoadData=%s</script>', $react_first_load_data);

然后,在您的 React 应用程序中,您首先检查此变量是否存在,如果存在则使用数据。如果没有,请返回像往常一样发出 REST 请求。

我知道这个答案非常具有架构性,但是有很多方法可以解决这个问题,这在很大程度上取决于您如何使用 WordPress 构建 React 实现。

于 2018-02-24T07:06:53.640 回答