当前位置: 首页 > 面试题库 >

是否可以将React组件传递给操纵p?

关昊天
2023-03-14
问题内容

我有一个带有一些componentDidMount逻辑的React组件:

export default class MyComponent {
    componentDidMount() {
        // some changes to DOM done here by a library  
    }

    render() {
        return (
            <div>{props.data}</div>
        );
    }
}

是否可以通过props传递此组件,以便componentDidMount()中的所有内容都被执行,以某种方式伪造以便截取屏幕截图?遵循以下原则:

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();

const html = ReactDOMServer.renderToString(<MyComponent data='' />); <-- but this skips the componentDidMount logic
await page.setContent(html);
await page.screenshot({ path: 'screenshot.png' });

我知道我可以使用page.goto(),但是我有一些复杂的登录逻辑,我想使用这样的快捷方式来避免,而是将所有需要的道具直接传递给组件?


问题答案:

在这里回答了这个问题。让我们在这里尝试相同的方法。

安装babel,webpack和puppeteer软件包。

{
  "name": "react-puppeteer",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "compile": "webpack",
    "build": "webpack -p",
    "start": "webpack && node pup.js"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "webpack": "^3.10.0",
    "webpack-dev-middleware": "^2.0.3"
  },
  "dependencies": {
    "puppeteer": "^0.13.0"
  }
}

准备Webpack配置,

const webpack = require('webpack');

const loaders = [
  {
    test: /\.jsx?$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    query: {
      presets: ['babel-preset-es2015', 'babel-preset-react'],
      plugins: []
    }
  }
];

module.exports = {
  entry: './entry.js',
  output: {
    path: __dirname,
    filename: 'bundle.js',
    libraryTarget: 'umd'
  },
  module: {
    loaders: loaders
  }
};

创建入口文件,在该文件上,而不是直接安装元素,而是将其导出到窗口,以便我们以后可以访问它。

import React from 'react';
import { render } from 'react-dom';

class Hello extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

// accept a name for example and a domNode where to render
function renderIt(name, domNode) {
  render(<Hello name={name} />, domNode);
}

window.renderIt = renderIt;

当我们运行时webpack,它将产生一个bundle.js文件。我们可以在木偶上使用它。

他们不建议使用puppeteer上的injectFile函数,因此我们将使其复活。这是一个示例仓库,您可以通过纱线添加它。

https://github.com/entrptaher/puppeteer-inject-file

现在,让我们创建一个操纵up脚本。

const puppeteer = require('puppeteer');
const injectFile = require('puppeteer-inject-file');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://github.com');
  await injectFile(page, require.resolve('./bundle.js'));
  await page.evaluate(() => {
    renderIt("Someone", document.querySelector('div.jumbotron.jumbotron-codelines > div > div > div > h1'));
  });
  await page.screenshot({ path: 'example.png' });
  await browser.close();
})();

当我们运行它时,我们得到以下结果,

在此处输入图片说明

如果添加componentDidMount()通话,我们也可以做到。但是,如果我们尝试进行更多修改,则必须使操纵up脚本等待其他问题中已多次讨论的脚本。

假设我们现在有一个状态,一旦加载组件,该状态将返回某些内容。

class Hello extends React.Component {
  state = {
    jokes: null
  };

  componentDidMount() {
    const self = this;
    const jokesUrl = `http://api.icndb.com/jokes/random?firstName=John&amp;lastName=Doe`;
    fetch(jokesUrl)
      .then(data => data.json())
      .then(data => {
        self.setState({
          jokes: data.value.joke
        });
      });
  }

  render() {
    if(!!this.state.jokes){
      return <p id='quote'>{this.state.jokes}</p>
    }
    return <h1>Hello, {this.props.name}</h1>;
  }
}

在操纵up的时候,我可以等待这样的元素,

  ...
  await injectFile(page, require.resolve('./bundle.js'));
  await page.evaluate(() => {
    renderIt("Someone", document.querySelector('div'));
  });
  await page.waitFor('p#quote');
  ...

我们可能需要babel-preset-stage-2,但我将留给您。结果就是这样

自己找出问题的其余部分:) …



 类似资料:
  • 我试图使用{children}将道具传递给子组件。 父亲组件: 子组件: 像这样使用它们: 我想把来自FatherComp的道具直接传递给ChildComp: 是否有可能实现我试图直接使用react功能组件而无需状态管理的目标? 谢谢

  • 我试图将类名传递给react组件以更改其样式,但似乎无法正常工作: 我试图通过传递具有各自风格的类的名称来改变药丸的风格。我是新来的,所以也许我做得不对。谢啦

  • 问题内容: 我尝试将函数传递给子组件。当用户单击每个子组件时,将调用onclick函数。此onclick函数将写入父组件。 父组件: 子组件: 在这一行: 它说没有定义handleClick …如何解决这个问题? 感谢您的回答。 问题答案: 您需要将Agents绑定到AgentsList:这是您的代码的一个简单示例,我不得不删除一些东西,但是您明白了: http://jsfiddle.net/vh

  • 问题内容: 我正在尝试访问DetailsPage组件中的 ID ,但无法访问它。我试过了 将参数传递给DetailsPage,但徒劳。 所以有什么想法如何将ID传递给DetailsPage吗? 问题答案: 如果要将props传递到路线内的组件,最简单的方法是利用,如下所示: 您可以使用以下内容访问道具: 将需要通过原路线的道具,否则你将只能得到内。

  • 问题内容: 我需要使用路由器将道具传递到组件。这是我的代码: 如您所见,isAuthenticated我想传递给Login组件的道具。 当我登录道具时, isAuthenticated 道具不存在。我做错了什么?如何正确通过道具?我关注了文档以及其他讨论。据我了解,它应该可以工作。的版本 做出反应路由器 和 反应路由器- DOM 是 4.0.0 问题答案: 像这样传递它: 它应该在“登录组件”中可

  • 问题内容: 我想做这样的事情: 但是我得到这个错误 对成员’init()’的不明确引用 我知道我可以写 但是我想知道是否还有另一种方式。 问题答案: 问题在于不存在 仅 具有参数的初始化程序。 __ 目前只存在: 尽管该参数具有默认值,但是编译器仅在初始化程序的调用位置为您“填充”该默认值。 获取对函数本身的引用时,不会部分应用默认参数值,编译器也不会为默认参数值的所有可能组合生成额外的重载。后者