React JSX中的不确定复选框

时间:2015-08-21 11:43:20

标签: javascript reactjs react-jsx

如何在JSX中呈现不确定的复选框?

以下是我尝试的内容:

render() {
  return <input type="checkbox" 
                checked={this.props.state === "checked"} 
                indeterminate={this.props.state === "indeterminate"} />
}

但是,indeterminate不是HTMLElement的属性,而是属性。如何从React / JSX设置属性?

8 个答案:

答案 0 :(得分:11)

我可能会创建一个复合组件,它封装了必要的钩子来设置或取消设置复选框的indeterminate属性。看起来你正在使用ES2015语法,所以我将在这里使用其中一些功能。

class IndeterminateCheckbox extends React.Component {
  componentDidMount() {
    if (this.props.indeterminate === true) {
      this._setIndeterminate(true);
    }
  }

  componentDidUpdate(previousProps) {
    if (previousProps.indeterminate !== this.props.indeterminate) {
      this._setIndeterminate(this.props.indeterminate);
    }
  }

  _setIndeterminate(indeterminate) {
    const node = React.findDOMNode(this);
    node.indeterminate = indeterminate;
  }

  render() {
    const { indeterminate, type, ...props } = this.props;
    return <input type="checkbox" {...props} />;
  }
}

// elsewhere

render() {
  return <IndeterminateCheckbox
           checked={this.props.state === "checked"} 
           indeterminate={this.props.state === "indeterminate"} />
}

工作示例:https://jsbin.com/hudemu/edit?js,output

答案 1 :(得分:7)

您可以使用componentDidMount步骤(在初始渲染后调用)来设置该属性:

componentDidMount() {
    React.findDOMNode(this).indeterminate = this.props.state === "indeterminate";
}

如果您希望使用后续渲染更新该属性,请在componentDidUpdate中执行相同的操作。

答案 2 :(得分:3)

另一种方法是使用带有回调的ref属性来设置DOM节点上的属性。例如:

render: function() {
  return (
    <input
        type="checkbox"
        ref={function(input) {
          if (input != null) {
            React.findDOMNode(input).indeterminate = this.props.indeterminate;
          }}
        {...this.props} />
  )
}

答案 3 :(得分:2)

我建议创建一个简单的组件(从coffeescript移植的代码,所以请注意,可能有一些简单的错别字):

const React = require('react');

module.exports = class IndeterminateCheckbox extends React.Component {
    componentDidMount() {
        this.refs.box.indeterminate = this.props.indeterminate;
    }

    componentDidUpdate(prevProps, prevState) {
        if(prevProps.indeterminate !== this.props.indeterminate) {
            this.refs.box.indeterminate = this.props.indeterminate;
        }
    }

    render() {
        return <input {...this.props} ref="box" type="checkbox"/>;
    }

}

现在你有一个简单的组件,其行为与复选框完全相同,支持indeterminate道具。请注意,这里有足够的改进空间,即为某些道具设置propTypes和正确的默认值,当然还要实现componentShouldUpdate只在需要时执行某些操作。

答案 4 :(得分:1)

不要使用React.findDOMNode(this)。 有风险。

export class SelectAll extends Component {
constructor(props) {
    super(props);
    this.state = {
        checked: false
    };
    this.myRef = React.createRef();
    this.onChange = this.onChange.bind(this);
    this.update = this.update.bind(this);
}

onChange(e) {
    const checked = e.target.checked;
    this.setState({
        checked: checked
    });
    this.selectAllNode.indeterminate = false;
}

update(state: {
    checked: Boolean,
    indeterminate: Boolean
}) {
    this.setState({
        checked: state.checked
    });
    this.myRef.current.indeterminate = state.indeterminate;
}

render() {
    return ( <
        input type = "checkbox"
        name = "selectAll"
        checked = {
            this.state.checked
        }
        onChange = {
            this.onChange
        }
        ref = {
            this.myRef
        }
        />
    );
}
}

答案 5 :(得分:-1)

React v15实施:

import React from 'react';

export default class Checkbox extends React.Component {
    componentDidMount() {
        this.el.indeterminate = this.props.indeterminate;
    }

    componentDidUpdate(prevProps, prevState) {
        if(prevProps.indeterminate !== this.props.indeterminate) {
            this.el.indeterminate = this.props.indeterminate;
        }
    }

    render() {
        const {indeterminate, ...attrs} = this.props;
        return <input ref={el => {this.el = el}} type="checkbox" {...attrs}/>;
    }
}

答案 6 :(得分:-1)

您也可以直接使用ref函数:

    Traceback (most recent call last):
  File "C:/Users/jakeb/Desktop/New folder/jakes exploit.py", line 6, in <module>
    exploitapi = ctypes.WinDLL(askopenfilename(filetypes=("All files", "*.*")))
  File "C:\Users\jakeb\AppData\Local\Programs\Python\Python35-32\lib\tkinter\filedialog.py", line 375, in askopenfilename
    return Open(**options).show()
  File "C:\Users\jakeb\AppData\Local\Programs\Python\Python35-32\lib\tkinter\commondialog.py", line 48, in show
    s = w.tk.call(self.command, *w._options(self.options))
_tkinter.TclError: bad file type "*.*", should be "typeName {extension ?extensions ...?} ?{macType ?macTypes ...?}?"
>>> 
ReactDOM.render(
  <label>
    <input
      type="checkbox"
      ref={ref => {
        if ( ref ) {
          ref.indeterminate = true;
        }
      }}
    />
    {' '}
    Un test
  </label>,
  document.getElementById('root')
);

答案 7 :(得分:-1)

取自 my tutorial,展示了它如何与最近的 React 功能配合使用。我希望这能帮助那些偶然发现这个老问题的人:

const App = () => {
  const [checked, setChecked] = React.useState(CHECKBOX_STATES.Empty);
 
  const handleChange = () => {
    let updatedChecked;
 
    if (checked === CHECKBOX_STATES.Checked) {
      updatedChecked = CHECKBOX_STATES.Empty;
    } else if (checked === CHECKBOX_STATES.Empty) {
      updatedChecked = CHECKBOX_STATES.Indeterminate;
    } else if (checked === CHECKBOX_STATES.Indeterminate) {
      updatedChecked = CHECKBOX_STATES.Checked;
    }
 
    setChecked(updatedChecked);
  };
 
  return (
    <div>
      <Checkbox
        label="Value"
        value={checked}
        onChange={handleChange}
      />
 
      <p>Is checked? {checked}</p>
    </div>
  );
};

const Checkbox = ({ label, value, onChange }) => {
  const checkboxRef = React.useRef();
 
  React.useEffect(() => {
    if (value === CHECKBOX_STATES.Checked) {
      checkboxRef.current.checked = true;
      checkboxRef.current.indeterminate = false;
    } else if (value === CHECKBOX_STATES.Empty) {
      checkboxRef.current.checked = false;
      checkboxRef.current.indeterminate = false;
    } else if (value === CHECKBOX_STATES.Indeterminate) {
      checkboxRef.current.checked = false;
      checkboxRef.current.indeterminate = true;
    }
  }, [value]);
 
  return (
    <label>
      <input ref={checkboxRef} type="checkbox" onChange={onChange} />
      {label}
    </label>
  );
};