如何知道在组件内部是否调用了prop?

时间:2019-02-04 13:49:45

标签: javascript reactjs

我有一个Form组件和一个Input组件。表单需要可重用,因此一切都只能通过Form的道具来完成。我想给Form包含一个道具,它是一个focusOn命名对象,应该包含一个id和一个event。 id是输入元素的id,如果调用event,则需要将其聚焦。简化代码:

//...Form

render () {
  const { focusOn, inputs } = this.props;
  
  const focus = inputId => {
    const { id: targetId, event } = focusOn;
    if (inputId === targetId) { return event; }
    else { return null; }
  };
  
  return (
    <div>
      inputs.map(({id, ...inputProps}) => (
        <Input focusOn={focus(id)} {...inputProps} />
      ))
    </div>
  )
}

//...Input

render () {
  const { focusOn, ...props } = this.props;
  
  if ("focusOn fires") {
    this.iRef.focus()
  }
  
  return <input ref={i = { this.iRef = i; }} {...props} />
}

问题是:我需要写什么而不是if ("focusOn fires") {/*...*/}部分?

1 个答案:

答案 0 :(得分:0)

据我了解,Form外部发生了某些事件,您希望在嵌套组件内部对其进行响应。

我相信您在代码中无法做到这一点,因为您需要改变思维方式。 Input不在乎事件触发的方式/位置/时间。 Input只关心新道具进入时是否应该集中精力(或做任何您想做的事情)。

基本上,您应该将这些内容分开。 使用这种新方法,您可以简单地执行以下操作:

您可以在操作in this codesandbox example中看到它。

//
// FORM COMPONENT
// You would pass down the "event" name down to the `Form` let's say as `parentEvent`
<Form
  parentEvent={event}
  inputs={[
    { id: "name", label: "name", event: "forName" },
  ]}
/>


//
// INSIDE OF FORM COMPONENT RENDER METHOD
return (
  <div>
    {inputs.map(({ event, ...inputProps }) => (
      //"shouldFocus" PROP THAT IS TRUE IF "parentEvent === input.event"
      <Input shouldFocus={parentEvent === event} {...inputProps} />
    ))}
  </div>
)

//
// INTPUT COMPONENT IMPLEMENTATION
class Input extends React.PureComponent {
  input = React.createRef();

  componentDidMount() {
    this.triggerFocus();
  }

  componentDidUpdate() {
    this.triggerFocus();
  }

  // FOCUS THE INPUT -> TRIGGERED ON FIRST RENDER AND RERENDER IF SHOULD FOCUS
  triggerFocus = () => {
    if (this.props.shouldFocus) {
      this.input.current.focus();
    }
  }

  render() {
    const { id, label } = this.props;

    return (
      <input id={label} ref={this.input} {...this.props} />
    );
  }
}

万一我误解了你要做什么,请告诉我。