我一直在转动我的车轮,试图找出一个具有redux形式的多个值的字段的最佳实践。
这就是我想要实现的目标。
那些buttoms是自定义组件。我通过可视化工作,使用自定义组件和import React, {Component} from 'react'
import {Field} from 'redux-form'
import * as icons from './../MultiSelectBtnGrid/icons'
const btnStyles = {
border: '3px solid #f6e9db',
background: 'transparent',
borderRadius: '45px',
width: '250px'
}
const btnSelectedStyles = {
border: '3px solid #27313c',
background: 'transparent',
borderRadius: '45px',
width: '250px'
}
class MultiSelectField extends Component {
constructor(props) {
super(props)
this.state = {selected: false}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState({selected: !this.state.selected})
this.props.input.onChange(!this.state.selected)
}
render() {
const {content, idx, input: {name}} = this.props
const {selected} = this.state
return (
<div className={'row m-auto rel'}>
<button type={'button'} className={`mb-1 p-3 ml-auto mr-auto`} style={selected ? btnSelectedStyles : btnStyles}
onClick={this.handleClick}>
{content}
<span style={{position: 'absolute', right: '15px', top: '0', bottom: '0', margin: 'auto'}}
className={'mb-1 d-flex justify-content-center align-items-center'}>{icons.plusIcon(selected)}</span>
</button>
<input type={'checkbox'} name={`${name}`} value={selected ? 'test' : null} checked={selected} />
</div>
)
}
}
export default class MultiSelectBtnGroup extends Component {
constructor(props) {
super(props)
this.state = {selected: props.formState.values[props.name]}
}
render() {
const {options, name} = this.props
return (
<div className={'container'}>
<div className={'row'}>
{options.map((option, idx) => {
return <Field
component={MultiSelectField}
name={name}
type='checkbox'
content={option.content}
key={idx}
{...this.props}
className={'col'}
idx={idx}/>
})}
</div>
</div>
)
}
}
来更新隐藏复选框字段的redux值。
这似乎是一个相当常见的用例,因为它本质上是一个多重问题。我知道使用react-widgets multiselect的文档roccomend但它似乎看起来那些符合我想要完成的按钮组样式。这是我到目前为止所看到的,但看到redux-form视图复选框是布尔值而不是数组,我不认为这对我有用。
<div class="details" itemscope itemtype="http://schema.org/Organization">
<p class="details-organisation">
<span itemprop="name">Test1</span>
</p>
<p class="details-block">
<span itemscope itemtype="http://schema.org/Person">
<span itemprop="name">
John Doe
</span>
</span>
</p>
<p class="details-block">
<span itemprop="telephone">
+44(0)123456789
</span>
</p>
<p class="details-block">
<span itemprop="email">
<a href="mailto:test@test123.com" data-event-category="Email a supplier" data-event-label="Test">test@test123.com</a>
</span>
</p>
</div>
答案 0 :(得分:1)
MultiSelectBtnGroup
应该是Field
的组件,使值成为表单状态中的数组。
以下是一个例子:
const MultiSelectBtnGroup = { input, options } => {
const values = input.value || [];
const handleClick = (value, select) => {
var index = values.indexOf(value);
if (select) {
if (index === -1) {
input.onChange([...values, value]);
}
} else {
if (index !== -1) {
input.onChange(values.filter(v => v !== value));
}
}
};
return (
<div className="row">
{options.map(o => {
const selected = values.indexOf(o.value) !== -1;
return (
<div className="col">
<div className="row m-auto rel">
<button
type="button"
className="mb-1 p-3 ml-auto mr-auto"
style={selected ? btnSelectedStyles : btnStyles}
onClick={e => handleClick(o.value, !selected)}
>
{o.content}
<span
style={{ position: 'absolute', right: '15px', top: 0, bottom: 0, margin: 'auto' }}
className="mb-1 d-flex justify-content-center align-items-center"
>
{icons.plusIcon(selected)}
</span>
</button>
<input
type="hidden"
name={name}
value={o.value}
checked={selected}
/>
</div>
</div>
);
})}
</div>
);
};
const Example = { options, name } => (
<div className="container">
<Field component={MultiSelectField} name={name} />
</div>
);
<input>
不需要在那里维护表单状态,但如果您想传统提交表单,则可能会有所帮助。