Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 优化React组件以使其可重用的最佳方法是什么?_Reactjs_Components_Reusability_React Component - Fatal编程技术网

Reactjs 优化React组件以使其可重用的最佳方法是什么?

Reactjs 优化React组件以使其可重用的最佳方法是什么?,reactjs,components,reusability,react-component,Reactjs,Components,Reusability,React Component,我是React的初学者,目前我只看到了基础知识。我有一个工作任务,就是使OptInPage.jsx中的服务条款组件可重用。我尝试了几件事情,但没有真正理解我在做什么,我查看了文档,但示例似乎比我的问题更基本。 我正在考虑提取页面并创建一个新的TermsOfServices组件来集成jsx标记。 这里的问题是,一方面,应该有一个“只读”属性来防止用户修改内容,另一方面,我真的不知道如何将道具从OptinPage组件传递到新的TermsOfServices组件。 如果我的问题看起来很愚蠢或者类似的话

我是React的初学者,目前我只看到了基础知识。我有一个工作任务,就是使OptInPage.jsx中的服务条款组件可重用。我尝试了几件事情,但没有真正理解我在做什么,我查看了文档,但示例似乎比我的问题更基本。 我正在考虑提取页面并创建一个新的TermsOfServices组件来集成jsx标记。 这里的问题是,一方面,应该有一个“只读”属性来防止用户修改内容,另一方面,我真的不知道如何将道具从OptinPage组件传递到新的TermsOfServices组件。 如果我的问题看起来很愚蠢或者类似的话,请提前道歉,我真的被它卡住了。提前感谢您的帮助

OptinPage.jsx

import API from 'api';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, intlShape } from 'react-intl';
import {
  Block,
  BlockTitle,
  Col,
  Fab,
  Icon,
  Link,
  NavRight,
  Navbar,
  Page,
  Popup,
  Preloader,
} from 'framework7-react';
import { connect } from 'react-refetch';
import ReactHtmlParser from 'react-html-parser';
import './OptInPage.scss';

class OptInPage extends PureComponent {
  static propTypes = {
    agreeTosFunc: PropTypes.func.isRequired,
    agreeTos: PropTypes.object,
    logout: PropTypes.func.isRequired,
    onSucceeded: PropTypes.func,
    opened: PropTypes.bool.isRequired,
    tos: PropTypes.object.isRequired,
  };

  static contextTypes = {
    apiURL: PropTypes.string,
    intl: intlShape,
    loginToken: PropTypes.string,
    logout: PropTypes.func,
    userId: PropTypes.string,
  };

  static defaultProps = {
    agreeTos: {},
    onSucceeded: () => {},
  };

  state = {
    currentTos: -1,
  };

  componentDidUpdate(prevProps) {
    const {
      agreeTos,
      onSucceeded,
      opened,
      tos,
    } = this.props;
    const { currentTos } = this.state;

    /* Reset currentTos on opened */
    if (!prevProps.opened && opened) {
      this.setState({ currentTos: -1 });
    }

    /* Prepare for first tos after receiving all of them */
    if (
      prevProps.tos.pending &&
      tos.fulfilled &&
      tos.value.length &&
      currentTos < 0
    ) {
      this.setState({ currentTos: 0 });
    }

    /* When sending ToS agreement is done */
    if (
      prevProps.agreeTos.pending &&
      agreeTos.fulfilled
    ) {
      onSucceeded();
    }
  }

  handleNext = () => {
    const { agreeTosFunc, tos } = this.props;
    const { currentTos: currentTosId } = this.state;
    const termsOfServices = tos.value;
    const done = currentTosId + 1 === termsOfServices.length;
    this.setState({ currentTos: currentTosId + 1 });
    if (done) {
      agreeTosFunc(termsOfServices.map((v) => v._id));
    }
  };

  render() {
    const { logout, opened, tos } = this.props;
    const { intl } = this.context;
    const { formatMessage } = intl;
    const { currentTos: currentTosId } = this.state;
    const termsOfServices = tos.value;
    const currentTermsOfServices = termsOfServices && termsOfServices[currentTosId];
    const loaded = termsOfServices && !tos.pending && tos.fulfilled;
    const htmlTransformCallback = (node) => {
      if (node.type === 'tag' && node.name === 'a') {
        // eslint-disable-next-line no-param-reassign
        node.attribs.class = 'external';
      }
      return undefined;
    };

    return (
      <Popup opened={opened} className="demo-popup-swipe" tabletFullscreen>
        <Page id="optin_page">
          <Navbar title={formatMessage({ id: 'press_yui_tos_title' })}>
            <NavRight>
              <Link onClick={() => logout()}>
                <FormattedMessage id="press_yui_comments_popup_edit_close" />
              </Link>
            </NavRight>
          </Navbar>
          { (!loaded || !currentTermsOfServices) && (
            <div id="optin_page_content" className="text-align-center">
              <Block className="row align-items-stretch text-align-center">
                <Col><Preloader size={50} /></Col>
              </Block>
            </div>
          )}
          { loaded && currentTermsOfServices && (
            <div id="optin_page_content" className="text-align-center">
              <h1>
                <FormattedMessage id="press_yui_tos_subtitle" values={{ from: currentTosId + 1, to: termsOfServices.length }} />
              </h1>
              <BlockTitle>
                {ReactHtmlParser(
                  currentTermsOfServices.title,
                  { transform: htmlTransformCallback },
                )}
              </BlockTitle>
              <Block strong inset>
                <div className="tos_content">
                  {ReactHtmlParser(
                    currentTermsOfServices.html,
                    { transform: htmlTransformCallback },
                  )}
                </div>
              </Block>
              <Fab position="right-bottom" slot="fixed" color="pink" onClick={() => this.handleNext()}>
                {currentTosId + 1 === termsOfServices.length &&
                  <Icon ios="f7:check" aurora="f7:check" md="material:check" />}
                {currentTosId !== termsOfServices.length &&
                  <Icon ios="f7:chevron_right" aurora="f7:chevron_right" md="material:chevron_right" />}
              </Fab>
              {currentTosId > 0 && (
              <Fab position="left-bottom" slot="fixed" color="pink" onClick={() => this.setState({ currentTos: currentTosId - 1 })}>
                <Icon ios="f7:chevron_left" aurora="f7:chevron_left" md="material:chevron_left" />
              </Fab>
              )}
            </div>
          )}
        </Page>
      </Popup>
    );
  }
}

export default connect.defaults(new API())((props, context) => {
  const { apiURL, userId } = context;
  return {
    tos: {
      url: new URL(`${apiURL}/tos?outdated=false&required=true`),
    },
    agreeTosFunc: (tos) => ({
      agreeTos: {
        body: JSON.stringify({ optIn: tos }),
        context,
        force: true,
        method: 'PUT',
        url: new URL(`${apiURL}/users/${userId}/optin`),
      },
    }),
  };
})(OptInPage);
从“API”导入API;
从“React”导入React,{PureComponent};
从“道具类型”导入道具类型;
从“react intl”导入{FormattedMessage,intlShape};
进口{
块
区块标题,
上校,
绝妙的,
偶像
链接
没错,
导航栏,
页
弹出窗口,
预载机,
}从“框架7反应”;
从'react refetch'导入{connect};
从“react html parser”导入ReactHtmlParser;
导入“/OptInPage.scss”;
类OptInPage扩展了PureComponent{
静态类型={
AgreetoFunc:PropTypes.func.isRequired,
agreeTos:PropTypes.object,
注销:需要PropTypes.func.isRequired,
onSucceeded:PropTypes.func,
打开:PropTypes.bool.isRequired,
tos:PropTypes.object.isRequired,
};
静态上下文类型={
apiURL:PropTypes.string,
intl:intlShape,
loginToken:PropTypes.string,
注销:PropTypes.func,
userId:PropTypes.string,
};
静态defaultProps={
同意:{},
onSucceed:()=>{},
};
状态={
当前TOS:-1,
};
componentDidUpdate(prevProps){
常数{
同意,
一旦成功,
开的,
托斯,
}=这是道具;
const{currentTos}=this.state;
/*将currentTos重置为打开状态*/
如果(!prevProps.opened&&opened){
this.setState({currentTos:-1});
}
/*收到所有tos后,准备第一个tos*/
如果(
prevProps.tos.pending&&
托斯&&
tos.value.length&&
电流tos<0
) {
this.setState({currentTos:0});
}
/*发送ToS协议时*/
如果(
prevProps.agreeTos.pending&&
同意
) {
onSucceed();
}
}
handleNext=()=>{
const{agreetosunc,tos}=this.props;
const{currentTos:currentTosId}=this.state;
const termsOfServices=tos.value;
const done=currentTosId+1==termsOfServices.length;
this.setState({currentTos:currentTosId+1});
如果(完成){
AgreetoFunc(termsOfServices.map((v)=>v._id));
}
};
render(){
const{logout,opened,tos}=this.props;
const{intl}=this.context;
const{formatMessage}=intl;
const{currentTos:currentTosId}=this.state;
const termsOfServices=tos.value;
const currentsofservices=termsOfServices&&termsOfServices[currentsofid];
const loaded=条款服务&&!tos.pending&&tos.COMPLETED;
常量HTMLTransferMcCallback=(节点)=>{
if(node.type=='tag'&&node.name=='a'){
//eslint禁用下一行无参数重新分配
node.attribs.class='external';
}
返回未定义;
};
返回(
注销()}>
{(!loaded | |!currentTermsOfServices)&&(
)}
{loaded&¤tTermsOfServices&&(
{ReactHtmlParser(
currentTermsOfServices.title,
{transform:htmlTransferMcCallback},
)}
{ReactHtmlParser(
currentTermsOfServices.html,
{transform:htmlTransferMcCallback},
)}
this.handleNext()}>
{currentTosId+1==termsOfServices.length&&
}
{currentTosId!==termsOfServices.length&&
}
{currentTosId>0&&(
this.setState({currentTos:currentTosId-1})}>
)}
)}
);
}
}
导出默认的connect.defaults(新API())((道具,上下文)=>{
const{apirl,userId}=context;
返回{
tos:{
url:newURL(`${APIRL}/tos?过时=false&required=true`),
},
同意功能:(tos)=>({
同意:{
body:JSON.stringify({optIn:tos}),
上下文
原力:没错,
方法:'放',
url:新url(`${APIRL}/users/${userId}/optin`),
},
}),
};
})(可选页);

如果我没听错,你需要这样的短信。 首先,您需要使用组件创建一个新文件,并将下一个代码放在那里

// don't forget to clean the unused imports
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, intlShape } from 'react-intl';
import {Block, BlockTitle, Col, Fab, Icon, Link, NavRight, Navbar, Page, Popup, Preloader } from 'framework7-react';
import ReactHtmlParser from 'react-html-parser';
export default class YourCLassName extends PureComponent<Props, State> {
    static propTypes = {
        currentTosId: PropTypes.object, // write correct type here
        termsOfServices: PropTypes.object, // write correct type here
        currentTermsOfServices: PropTypes.string, // write correct type here
        handleNext: PropTypes.func, // write correct type here
        handlePrev: PropTypes.func, // write correct type here
    };

    function htmlTransformCallback (node) => {
      if (node.type === 'tag' && node.name === 'a') {
        // eslint-disable-next-line no-param-reassign
        node.attribs.class = 'external';
      }
      return undefined;
    };


  render() {
    const { currentTosId, termsOfServices, currentTermsOfServices } = this.props;

    return (
        <div id="optin_page_content" className="text-align-center">
          <h1>
            <FormattedMessage id="press_yui_tos_subtitle" values={{ from: currentTosId + 1, to: termsOfServices.length }} />
          </h1>
          <BlockTitle>
            {ReactHtmlParser(
              currentTermsOfServices.title,
              { transform: htmlTransformCallback },
            )}
          </BlockTitle>
          <Block strong inset>
            <div className="tos_content">
              {ReactHtmlParser(
                currentTermsOfServices.html,
                { transform: htmlTransformCallback },
              )}
            </div>
          </Block>
          <Fab position="right-bottom" slot="fixed" color="pink" onClick={() => this.props.handleNext()}>
            {currentTosId + 1 === termsOfServices.length &&
              <Icon ios="f7:check" aurora="f7:check" md="material:check" />}
            {currentTosId !== termsOfServices.length &&
              <Icon ios="f7:chevron_right" aurora="f7:chevron_right" md="material:chevron_right" />}
          </Fab>
          {currentTosId > 0 && (
          <Fab position="left-bottom" slot="fixed" color="pink" onClick={() => this.props.handlePrev())}>
            <Icon ios="f7:chevron_left" aurora="f7:chevron_left" md="material:chevron_left" />
          </Fab>
          )}
        </div>
    );
}
}
//不要忘记清理未使用的导入
从“React”导入React,{PureComponent};
从“道具类型”导入道具类型;
从“react intl”导入{FormattedMessage,intlShape};
从“framework7 react”导入{Block、BlockTitle、Col、Fab、Icon、Link、NavRight、Navbar、Page、Popup、preload};
从“react html parser”导入ReactHtmlParser;
导出默认类YourCLassName扩展PureComponent{
静态类型={
currentTosId:PropTypes.object,//在此处写入正确的类型
termsOfServices:PropTypes.object,//write
<YourComponentName currentTosId={this.state.currentTosId} termsOfServices={termsOfServices} currentTermsOfServices={currentTermsOfServices} handleNext={this.handleNext} handlePrev={this.handlePrev} />