How do I render an indeterminate checkbox in JSX?
Here's what I've tried:
render() {
return <input type="checkbox"
checked={this.props.state === "checked"}
indeterminate={this.props.state === "indeterminate"} />
}
However, indeterminate
is not an attribute on the HTMLElement
, but a property. How do I set properties from React / JSX?
You can use the componentDidMount
step (which is invoked after the initial rendering) to set that property:
componentDidMount() {
React.findDOMNode(this).indeterminate = this.props.state === "indeterminate";
}
If you want that property to be updated with subsequent renders, do the same thing in componentDidUpdate
also.
I would probably create a composite component that encapsulates the necessary hooks to set or unset the checkbox's indeterminate
property. It looks like you're using ES2015 syntax, so I'll use some of those features here.
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"} />
}
Working example: https://jsbin.com/hudemu/edit?js,output
I'd suggest creating a simple component (code ported from coffeescript so mind you, might have some simple typos):
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"/>;
}
}
Now you have a simple component that behaves exactly like a checkbox, that supports the indeterminate
prop. Note there's plenty of room for improvements here, namely setting propTypes and proper defaults for some props, and of course implementing componentShouldUpdate
to only do something when needed.
An alternative would be to use a ref
attribute with a callback to set the property on the DOM node. For example:
render: function() {
return (
<input
type="checkbox"
ref={function(input) {
if (input != null) {
React.findDOMNode(input).indeterminate = this.props.indeterminate;
}}
{...this.props} />
)
}
You can also use the ref function directly:
ReactDOM.render(
<label>
<input
type="checkbox"
ref={input => {
if (input) {
input.indeterminate = true;
}
}}
/>
{' '}
Un test
</label>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
React v15 implementation:
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}/>;
}
}
来源:https://stackoverflow.com/questions/32139455/indeterminate-checkbox-in-react-jsx