警告:ReactDOMComponent:不要访问 DOM 节点的 .props

Warning: ReactDOMComponent: Do not access .props of a DOM node

我从新的 React 0.14.x 收到这个错误:

Warning: ReactDOMComponent: Do not access .props of a DOM node; instead, recreate the props as `render` did originally or read the DOM properties/attributes directly from this node (e.g., this.refs.box.className).

it('allows for FluxComponents through the tree via context', () => {
  const flux = new Flux();
  const actions = flux.getActions('test');

  class TopView extends React.Component {
    render() {
      return (
        <FluxComponent flux={flux}>
          <SubView />
        </FluxComponent>
      );
    }
  }

  class SubView extends React.Component {
    render() {
      return <SubSubView />;
    }
  }

  class SubSubView extends React.Component {
    render() {
      return (
        <FluxComponent connectToStores="test">
          <div />
        </FluxComponent>
      );
    }
  }

  const tree = TestUtils.renderIntoDocument(
    <TopView />
  );

  const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div');

  actions.getSomething('something good');
  expect(div.props.something).to.equal('something good');
});

在我的情况下获取道具和上下文的正确方法是什么?

组件看起来像:

import React from 'react';
import { instanceMethods, staticProperties } from './reactComponentMethods';
import assign from 'object-assign';

class FluxComponent extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.initialize();

    this.state = this.connectToStores(props.connectToStores, props.stateGetter);

    this.wrapChild = this.wrapChild.bind(this);
  }

  wrapChild(child) {
    return React.cloneElement(
      child,
      this.getChildProps()
    );
  }

  getChildProps() {
    const {
      children,
      render,
      connectToStores,
      stateGetter,
      flux,
      ...extraProps } = this.props;

    return assign(
      { flux: this.getFlux() },
      this.state,
      extraProps
    );
  }

  render() {
    let { children, render: internalRender } = this.props;

    if (typeof internalRender === 'function') {
      return internalRender(this.getChildProps(), this.getFlux());
    }

    if (!children) return null;

    if (!Array.isArray(children)) {
      const child = children;
      return this.wrapChild(child);
    } else {
      return <span>{React.Children.map(children, this.wrapChild)}</span>;
    }
  }
}

assign(
  FluxComponent.prototype,
  instanceMethods
);

assign(FluxComponent, staticProperties);

export default FluxComponent;

我建议使用 DOM 属性 等效项来避免警告。例如,如果您正在检查 id 属性,请使用 id 属性:

旧:

expect(div.props.id).to.equal('something good');

新:

expect(div.id).to.equal('something good');

所以我找到了从 DOM 组件获取原始属性值的解决方案(但对于对象,您将需要 React 组件)。看起来如下:

it('allows for FluxComponents through the tree via context', () => {
  const flux = new Flux();
  const actions = flux.getActions('test');

  class TopView extends React.Component {
    render() {
      return (
        <FluxComponent flux={flux}>
          <SubView />
        </FluxComponent>
      );
    }
  }

  class SubView extends React.Component {
    render() {
      return <SubSubView />;
    }
  }

  class SubSubView extends React.Component {
    render() {
      return (
        <FluxComponent connectToStores="test">
          <InnerWithData />
        </FluxComponent>
      );
    }
  }

  class InnerWithData extends React.Component {
    render() {
      return (
        <div data-something={this.props.something} />
      );
    }
  }

  const tree = TestUtils.renderIntoDocument(
    <TopView />
  );
  const div = TestUtils.findRenderedDOMComponentWithTag(tree, 'div');

  actions.getSomething('something good');
  expect(div.getAttribute('data-something')).to.equal('something good');
});

这基本上意味着将 prop 值放入 DOM 属性中。