17

我正在使用两个组件并且我正在使用这种模式:子组件应该尽可能地保持隔离 - 它正在处理自己的验证错误。父组件应检查子组件之间存在依赖关系的错误。所以,就我而言:password字段和password confirmation字段。

这是我的代码:

a) 注册(父母)

设置初始状态。

 constructor() {
     super();

     this.state = {
         isPasswordMatching: false
     };
 }

render()方法中,我正在输出我的子组件。通过 prop 调用callback我正在isPasswordMatching()通过绑定 parent 的this. 目标是可以在子组件中调用该方法。

<TextInput
    id={'password'}
    ref={(ref) => this.password = ref}
    callback={this.isPasswordMatching.bind(this)}
    // some other unimportant props
/>

<TextInput
    id={'passwordConfirm'}
    ref={(ref) => this.passwordConfirm = ref}
    ...

isPasswordMatching()方法是检查密码是否匹配(通过 refsthis.passwordthis.passwordConfirm),然后更新状态。请注意,此方法在子项内部调用(密码或密码确认)。

isPasswordMatching() {
    this.setState({
        isPasswordMatching: this.password.state.value === this.passwordConfirm.state.value
    });
}

b) 文本输入(子)

设置初始状态。

constructor() {
    super();

    this.state = {
        value: '',
        isValid: false
    };
}

完成模糊验证并更新状态。

onBlur(event) {

    // doing validation and preparing error messages

    this.setState({
        value: value,
        isValid: this.error === null
    });
}

最新的。回调道具被调用。

componentDidUpdate(prevProps) {
    if (prevProps.id === 'password' || prevProps.id === 'passwordConfirm') {
        prevProps.callback();
    }
}

问题

不知何故,我的裁判丢失了。设想:

  1. 父组件是渲染器
  2. 子组件被渲染
  3. 我正在输入一个输入字段并退出(这会调用onBlur()方法) - 状态得到更新,子组件被渲染
  4. componentDidUpdate()被调用,prevProp.callback()以及
  5. 当使用isPasswordMatching()我正在输出的方法时this.passwordthis.passwordConfirm它们是具有预期参考值的对象。更新父组件的状态 - 组件被渲染。
  6. this.password然后再次渲染所有子项,更新组件,调用回调,但这次this.passwordConfirmnull

我不知道为什么参考文献有点丢失。我应该做一些不同的事情吗?先感谢您。

4

2 回答 2

18

请参阅此处的反应文档,其中包含重要警告并建议何时使用或不使用 refs。

请注意,当引用的组件被卸载并且每当 ref 更改时,旧的 ref 将被调用,并使用 null 作为参数。这可以防止在存储实例的情况下发生内存泄漏,如第二个示例所示。另请注意,在此处的示例中使用内联函数表达式编写 ref 时,React 每次都会看到不同的函数对象,因此在每次更新时,在使用组件实例调用 ref 之前,都会立即使用 null 调用 ref。

于 2016-07-16T08:06:59.243 回答
7

我不确定这是否回答了@be-codified 的问题,但我发现这遇到了类似的问题。就我而言,事实证明这是由于使用了功能组件。

https://reactjs.org/docs/refs-and-the-dom.html#refs-and-functional-components

Refs 和功能性组件 你不能在功能性组件上使用 ref 属性,因为它们没有。如果你需要一个对它的引用,你应该将组件转换为一个类,就像你需要生命周期方法或状态时所做的那样。
但是,只要您引用 DOM 元素或类组件,您就可以在功能组件中使用 ref 属性

该文档解释了如果您可以控制您尝试呈现的组件,您应该如何解决该问题。

但是在我的情况下,该组件来自第 3 方库。所以,简单地包装组件就可以了。

在职的

<div ref={element => this.elementName = element}>
    <FunctionalComponent />
</div>

不工作
将 this.elementName 设置为null

<FunctionalComponent ref={element => this.elementName = element} />

希望这可以帮助任何人像我一样找到这个问题。

于 2017-12-01T19:42:23.257 回答