Skip to content

Commit

Permalink
Merge pull request #1176 from npham49/react/select-migration
Browse files Browse the repository at this point in the history
refactor: Migrate Select component to functional component using useState hook
  • Loading branch information
mattwoberts authored Jul 11, 2024
2 parents cfc272f + 3dee754 commit a108bed
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 58 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module github.com/getfider/fider

go 1.22.0
go 1.22

require (
github.com/aws/aws-sdk-go v1.41.14
Expand Down
97 changes: 40 additions & 57 deletions public/components/common/form/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,75 +19,58 @@ interface SelectProps {
onChange?: (option?: SelectOption) => void
}

interface SelectState {
selected?: SelectOption
}

export class Select extends React.Component<SelectProps, SelectState> {
constructor(props: SelectProps) {
super(props)
this.state = {
selected: this.getOption(props.defaultValue),
}
}

private getOption(value?: string): SelectOption | undefined {
if (value && this.props.options) {
const filtered = this.props.options.filter((x) => x.value === value)
export const Select: React.FunctionComponent<SelectProps> = (props) => {
const getOption = (value?: string) => {
if (value && props.options) {
const filtered = props.options.filter((x) => x.value === value)
if (filtered && filtered.length > 0) {
return filtered[0]
}
}
}

private onChange = (e: React.FormEvent<HTMLSelectElement>) => {
const [selected, setSelected] = React.useState<SelectOption | undefined>(getOption(props.defaultValue))
const onChange = (e: React.FormEvent<HTMLSelectElement>) => {
let selected: SelectOption | undefined
if (e.currentTarget.value) {
const options = this.props.options.filter((o) => o.value === e.currentTarget.value)
const options = props.options.filter((o) => o.value === e.currentTarget.value)
if (options && options.length > 0) {
selected = options[0]
}
}

this.setState({ selected }, () => {
if (this.props.onChange) {
this.props.onChange(this.state.selected)
}
})
setSelected(selected)
if (props.onChange) {
props.onChange(selected)
}
}

public render() {
const options = this.props.options.map((option) => {
return (
<option key={option.value} value={option.value}>
{option.label}
</option>
)
})

return (
<ValidationContext.Consumer>
{(ctx) => (
<>
<div className="c-form-field">
{!!this.props.label && <label htmlFor={`input-${this.props.field}`}>{this.props.label}</label>}
<select
className={classSet({
"c-select": true,
"c-select--error": hasError(this.props.field, ctx.error),
})}
id={`input-${this.props.field}`}
defaultValue={this.props.defaultValue}
onChange={this.onChange}
>
{options}
</select>
<DisplayError fields={[this.props.field]} error={ctx.error} />
{this.props.children}
</div>
</>
)}
</ValidationContext.Consumer>
)
}
return (
<ValidationContext.Consumer>
{(ctx) => (
<>
<div className="c-form-field">
{!!props.label && <label htmlFor={`input-${props.field}`}>{props.label}</label>}
<select
className={classSet({
"c-select": true,
"c-select--error": hasError(props.field, ctx.error),
})}
value={selected?.value}
id={`input-${props.field}`}
defaultValue={props.defaultValue}
onChange={onChange}
>
{props.options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<DisplayError fields={[props.field]} error={ctx.error} />
{props.children}
</div>
</>
)}
</ValidationContext.Consumer>
)
}

0 comments on commit a108bed

Please sign in to comment.