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

时间:2015-11-30 09:10:43

标签: javascript dom reactjs tdd flux

我从新的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;

2 个答案:

答案 0 :(得分:1)

我建议使用等效的DOM属性来避免警告。例如,如果您要检查id道具,请使用id属性:

旧:

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

新:

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

答案 1 :(得分:1)

所以我找到了一个从DOM组件中获取原始prop值的解决方案(但是对于需要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属性中。