为什么有时可以将ref附加到无状态函数?

时间:2016-03-22 01:10:52

标签: reactjs redux

来自React docs(我的斜体):

  

Refs可能未附加到无状态函数,因为该组件没有后备实例。您始终可以将无状态组件包装在标准复合组件中,并将ref附加到组合组件。

0.14 changelog(我的斜体):

  

由于没有为功能组件创建组件实例,因此添加到其中的任何 ref将评估为null 。功能组件没有生命周期方法,但您可以将.propTypes和.defaultProps设置为函数的属性。

在Dan Abramov的Redux egghead tutorials讲座21中,我们编写了以下无状态功能组件来添加待办事项:

const AddTodo = ({
  onAddClick,
}) => {
  let input;
  return <div>
    <input ref = {node => {
        input = node;
      }} />

    <button onClick = {() => {
          onAddClick(input.value)
          input.value='';
        }}>Add Todo</button>

  </div>
}

当放入应用程序的复合组件时,这实际上有效,并且ref没有按照React docs的承诺返回null

复合组件中AddTodo的实现如下所示:

class TodoApp extends Component {

  render() {
    //console.log(store.getState());
    log();
    const {
      todos,
      visibilityFilter,
    } = this.props;
    const visibleTodos = getVisibleTodos(
      todos,
      visibilityFilter
    );
    return (
      <div>
          <AddTodo onAddClick = {
              (input) => {
                store.dispatch({
                  type:'ADD_TODO',
                  text: input,
                  id: nextTodoId++,
                })
              }
            }/>

文档确实说我们可以将无状态组件包装在复合组件中,并将ref 附加到组合组件。这里的关键是复合组件的附件,但我的参考仍然附加到我的实现中的无状态AddTodo

我的问题是:

  1. AddTodo这里真的是一个无状态的功能组件,不是吗?

  2. 如果没有,为什么不呢? (它看起来确实像一个,但我可能会忽略无国籍意味着什么的显着特征)

  3. 如果问题1为是,那么在这里使用ref的行为如何与React文档中的内容一致?

1 个答案:

答案 0 :(得分:4)

广告1)是的,AddTodo是无状态的功能组件。

广告2)这里无事可做: - )

广告3)您要将引用添加到input,而不是AddTodo - 这就是它的工作原理。如果你查看你引用的文档页面,

  

将ref附加到像<div />这样的DOM组件时,可以返回DOM节点;

这正是你想要的代码。

无法做的是:<AddTodo ref={component => ...} />,因为没有AddTodo的实例可以传递给ref函数。