0

How do i accept conditional attributes in react.js

below is my search component, I want the InputGroup to have a onSubmit attribute if the onSubmit function is passed and an onChange attribute if an onChange function is passed

class QueryBar extends PureComponent {
  render() {
    const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
    return (
      <form
        style={{ width }}
        onSubmit={e => {
          e.preventDefault();
          onSubmit(e.target[0].value);
        }}
      >
        <InputGroup
          placeholder={placeholder}
          width={width}
          leftIcon="search"
          rightElement={
            <Button
              type="submit"
              icon={leftIcon}
              minimal={true}
              intent={Intent.PRIMARY}
            />
          }
        />
      </form>
    );
  }
}

QueryBar.propTypes = {
  width: PropTypes.number,
  placeholder: PropTypes.string,
  leftIcon: PropTypes.oneOfType(['string', 'element']),
  onSubmit: PropTypes.func
};

QueryBar.defaultProps = {
  placeholder: 'Search...',
  leftIcon: 'arrow-right',
  width: 360
};
export default QueryBar;
1
  • You shouldn't use conditional attributes but rather handle that in a function. In the function you can check the state of the input and based on that you can make the transformation as desired (update, change, submit, ..etc) Commented Jul 18, 2019 at 8:20

3 Answers 3

1

jsx elements can also accept objects. Initialize an object that contains information for both situations and then add a conditional to add a function if it exists in the props passed in.

render() {
    const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
    const inputGroupProps = {
    placeholder,
    width,
    leftIcon: 'search',
    rightElement: (
        <Button
        type="submit"
        icon={leftIcon}
        minimal={true}
        intent={Intent.PRIMARY}
        />
      )
    }
    if (onChange) {
    inputGroupProps.onChange = onChange
    }
    if (onSubmit) {
        inputGroupProps.onSubmit = onSubmit
    }
    return (
    <form
        style={{ width }}
        onSubmit={e => {
        e.preventDefault();
        onSubmit(e.target[0].value);
        }}
    >
        <InputGroup {...inputGroupProps} />
    </form>
    );
}

While I do not recommend it, adding both are technically OK because a prop that isn't passed in from the parent but destructured, will be undefined. I don't recommend this because it is not expressive and will probably confuse you in the future

<InputGroup
placeholder={placeholder}
width={width}
leftIcon="search"
rightElement={
    <Button
    type="submit"
    icon={leftIcon}
    minimal={true}
    intent={Intent.PRIMARY}
    />
}
onChange={onChange} // will be undefined and have no behavior if parent does not pass an onChange prop
onSubmit={onSubmit} // same for this one
/>
Sign up to request clarification or add additional context in comments.

Comments

0

You can pass null if its not there i.e :

<InputGroup
          placeholder={placeholder}
          width={width}
          leftIcon="search"
          onChange={onChangeFn?onChangeFn:null} 
          onSubmit={onSubmitFn ? onSubmitFn : null}
          rightElement={
            <Button
              type="submit"
              icon={leftIcon}
              minimal={true}
              intent={Intent.PRIMARY}
            />
          }
        />

It will make sure if function is there then call function otherwise it will not anything.

4 Comments

I think it's better to use a logical expression which will express to false value. false is also not passed.
@FacyoKouch It can be. But Isn't its redundant as for only two condition we write same component twice??
A logical expression is { onSubmitFn && onSubmitFn }. So using the && instead of the ?, so, no, I don't find it redundant at all
@FacyoKouch Ohh I understand different approach. It's also a good way.
0

I would do this:

The idea is to have an Object optionalProps, an empty object for any possible conditional properties, when a property exists, we add it to the object, then, in the InputGroup component we apply it as {...optionalProps} which will extract any added properties to the object, and return nothing if null.

we could follow another approach: onChange={onChange && onChange}

But, note This will return false as a value for cases where onChange doesn't exist.

  render() {
    const { placeholder, leftIcon, onSubmit, onChange, width } = this.props;
    let optionalProps = {};
    if(onChange){
      optionalProps['onChange'] = onChange;
    }
    if(onSubmit){
      optionalProps['onSubmit'] = onSubmit;
    }

    return (
      <form
        style={{ width }}
        onSubmit={e => {
          e.preventDefault();
          onSubmit(e.target[0].value);
        }}
      >
        <InputGroup
          placeholder={placeholder}
          width={width}
          leftIcon="search"
          {...optionalProps}
          rightElement={
            <Button
              type="submit"
              icon={leftIcon}
              minimal={true}
              intent={Intent.PRIMARY}
            />
          }
        />
      </form>
    );
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.