React:是否有类似于node.textContent的东西?

14

我想测试一个React组件的子级并获取其子级的文本表示。是否有一种类似于node.textContent的工具可用于React?我希望有像这样的东西:

let testComponent = (
  <Test>
    <p>abc</p>
    <p>abc2</p>
  </Test>
);

expect(testComponent.props.children.toString()).to.equal('abc abc2');

react-testing-library可能是您在前端代码测试方面所提出的许多问题的答案。不要测试内部细节,而是测试用户实际看到的内容。 - marzelin
5个回答

31

react-getNodeText Sandbox screenshot

// this is an out of date version, use the one below
const getNodeText = node => {
  if (['string', 'number'].includes(typeof node)) return node
  if (node instanceof Array) return node.map(getNodeText).join('')
  if (typeof node === 'object' && node) return getNodeText(node.props.children)
}

https://codesandbox.io/s/react-getnodetext-h21ss

// in the screenshot above

const heading = <Heading>Hello <span className="red">Code</span>Sandbox</Heading>

return (
  <div>
    {heading}
    <pre ref={printInnerHTML}/>
    <pre>{getNodeText(heading)}</pre>
  </div>
)

TypeScript更新

const getNodeText = (node: React.ReactNode): string => {
  if (node == null) return ''

  switch (typeof node) {
    case 'string':
    case 'number':
      return node.toString()

    case 'boolean':
      return ''

    case 'object': {
      if (node instanceof Array)
        return node.map(getNodeText).join('')

      if ('props' in node)
        return getNodeText(node.props.children)
    } // eslint-ignore-line no-fallthrough

    default: 
      console.warn('Unresolved `node` of type:', typeof node, node)
      return ''
  }
}

1
感谢这个非常棒的解决方案 :) - Pavan
@Pavan 谢谢你的赞美。 - Qwerty
4
如果你和我一样被 typeof node === 'object' && node 搞糊涂了,那么需要知道的是 null 的类型是 object,所以这个检查可以防止 null。 - niryo

2
你可以编写一个小函数,遍历React元素并获取文本。
import React from 'react';
import renderer from 'react-test-renderer';

const MyComponent = ()=>{
  return <div>
    <p>hello</p>
    <div>
      <p>to</p>
    </div>
  </div>
}

const getText=(tree)=>{
  if(typeof tree === 'string'){
    return tree;
  }
  return tree.children.map((child)=>{
    return getText(child);
  }).join('');
}


it('renders without crashing', () => {
  const tree = renderer
    .create(<MyComponent />)
    .toJSON();

  expect(getText(tree)).toBe("helloto");
});

这里的MyComponent是你需要获取文本的组件。

getText()方法将以字符串形式获取组件中的所有文本节点。


你还需要处理 booleannumbernull 这些都是 tree 可能的类型,参见 type React.ReactNode - Qwerty

0

对于 ES6 组件,您可以使用 getDomNode()findDomNode(),然后使用普通的 DOM 方法。

如果您正在寻找 React 的方式 - 实际上并没有一个,因为父组件对其子组件是相对盲目的。


0

0

你绝对应该尝试使用Jest(我通常与React Testing Library一起使用)。基本上,你可以拍摄组件的快照,这样你不仅可以测试组件中包含的文本,还可以测试布局、元素参数等。它非常方便检测不必要的更改。它还具有很棒的功能,如代码覆盖率

import React from 'react';
import { cleanup, render } from "@testing-library/react";
import { MyComponent } from "./MyComponent";

describe("MyComponent", (): void => {
  afterEach(cleanup);
  it("renders properly", (): void => {
    const { container } = render(
      <MyComponent prop1="myprop1" prop2="myprop2" />
    );
    expect(container).toMatchSnapshot();
  });
});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接