Skip to content

Commit

Permalink
Merge pull request #459 from JeromeLin/master
Browse files Browse the repository at this point in the history
fix: fix input bug when value is undefined, fix controlled and uncont…
  • Loading branch information
JeromeLin committed May 18, 2020
2 parents dbdaf7e + 7a335b8 commit e3bb8d1
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 123 deletions.
40 changes: 18 additions & 22 deletions components/input/InputBase.tsx
Expand Up @@ -21,24 +21,23 @@ export default class InputBase extends PureComponent<InputBaseProps, any> {
constructor(props) {
super(props);
this.state = {
focused: false,
value: props.defaultValue || props.value || '',
focused: props.autoFocus || false,
value: props.value || props.defaultValue || '',
};
}

componentDidMount() {
const { autoFocus } = this.props;
const { focused } = this.state;

if (autoFocus || focused) {
if (focused) {
this.input.focus();
}
}

static getDerivedStateFromProps(nextProps) {
if ('value' in nextProps) {
return {
value: nextProps.value,
value: nextProps.value || nextProps.defaultValue || '',
};
}
return null;
Expand Down Expand Up @@ -81,16 +80,19 @@ export default class InputBase extends PureComponent<InputBaseProps, any> {

onChange = (e) => {
const { onChange } = this.props;
if (!this.state.focused) {
this.setState({
focused: true,
});
const { focused } = this.state;
const { value } = e.target;

if (!focused) {
this.setState({ focused: true });
}
this.setState({
value: e.target.value,
});
if (onChange) {
onChange(e.target.value);

if (!('value' in this.props)) {
this.setState({ value });
}

if (typeof onChange === 'function') {
onChange(value);
}
};

Expand Down Expand Up @@ -161,8 +163,7 @@ export default class InputBase extends PureComponent<InputBaseProps, any> {
...rest
} = this.props;

const { value } = this.state;
const { focused } = this.state;
const { value, focused } = this.state;
const showClearIcon = clearable && ('value' in this.props) && ('onChange' in this.props);

const cls = classnames(prefixCls, className, {
Expand All @@ -172,15 +173,10 @@ export default class InputBase extends PureComponent<InputBaseProps, any> {
[`${prefixCls}--readonly`]: readOnly,
});

const valueProps: any = {};
if ('value' in this.props) {
valueProps.value = value;
}

const renderInput = (
<input
{...rest}
{...valueProps}
value={('value' in this.props) ? value : undefined}
autoComplete="off"
ref={(ele) => { this.input = ele; }}
type={type}
Expand Down
14 changes: 7 additions & 7 deletions components/input/InputNumber.tsx
Expand Up @@ -42,8 +42,8 @@ export default class InputNumber extends Component<InputNumberProps, any> {
static getDerivedStateFromProps(nextProps, state) {
if ('value' in nextProps && nextProps.value !== state.prevValue) {
return {
value: nextProps.value,
prevValue: nextProps.value,
value: nextProps.value || nextProps.defaultValue || '',
prevValue: nextProps.value || nextProps.defaultValue || '',
};
}
return null;
Expand Down Expand Up @@ -85,13 +85,13 @@ export default class InputNumber extends Component<InputNumberProps, any> {
? String(value).slice(0, String(value).length - 1)
: value + key;

if (newValue !== value) {
const { onChange } = this.props;
if (!('value' in this.props)) {
this.setState({ value: newValue }, () => this.scrollToEnd());
}

if (typeof onChange === 'function') {
onChange(newValue);
}
const { onChange } = this.props;
if (typeof onChange === 'function') {
onChange(newValue);
}
};

Expand Down
21 changes: 14 additions & 7 deletions components/input/InputTextarea.tsx
Expand Up @@ -22,7 +22,7 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any
constructor(props) {
super(props);
this.state = {
length: (props.value || props.defaultValue || '').length,
value: props.value || props.defaultValue || '',
focused: props.focused || false,
};
}
Expand All @@ -38,8 +38,8 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any
static getDerivedStateFromProps(nextProps) {
if ('focused' in nextProps || 'value' in nextProps) {
return {
focused: nextProps.focused,
length: (nextProps.value || nextProps.defaultValue || '').length,
value: nextProps.value || nextProps.defaultValue || '',
focused: nextProps.focused || false,
};
}
return null;
Expand Down Expand Up @@ -123,8 +123,11 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any
onChange = (e) => {
const { onChange } = this.props;
const { value } = e.target;
const length = countSymbols(value);
this.setState({ length });

if (!('value' in this.props)) {
this.setState({ value });
}

if (typeof onChange === 'function') {
onChange(value);
}
Expand All @@ -151,12 +154,15 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any
type,
...rest
} = this.props;
const { length } = this.state;

const cls = classnames(prefixCls, `${prefixCls}--textarea`, className, {
[`${prefixCls}--disabled`]: disabled,
[`${prefixCls}--readonly`]: readOnly,
});

const { value } = this.state;
const length = countSymbols(value);

const textLengthRender = showLength
&& maxLength
&& (
Expand All @@ -168,6 +174,7 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any
const renderInput = (
<textarea
{...rest}
value={('value' in this.props) ? value : undefined}
ref={(ele) => { this.input = ele; }}
maxLength={maxLength}
disabled={disabled}
Expand All @@ -182,7 +189,7 @@ export default class InputTextarea extends PureComponent<InputTextareaProps, any

const renderText = (
<div className={`${prefixCls}__content`} ref={(ele) => { this.input = ele; }}>
{rest.value || rest.defaultValue}
{value}
</div>
);

Expand Down
168 changes: 81 additions & 87 deletions components/input/demo.md
Expand Up @@ -5,81 +5,83 @@
## 基本用法

```jsx
import { useState } from 'react';
import { Input, Cell } from 'zarm';

class Demo extends React.Component {
state = {
inputValue: '',
};

handleInputChange = (value) => {
this.setState({
inputValue: value,
});
}

render() {
return (
<>
<Cell title="单行文本">
<Input
clearable
type="text"
placeholder="请输入"
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
</Cell>
<Cell title="多行文本"><Input type="text" rows={3} placeholder="请输入" /></Cell>
</>
)
}
const Demo = () => {
const [title, setTitle] = useState('');
const [content, setContent] = useState('');

return (
<>
<Cell title="单行文本">
<Input
clearable
type="text"
placeholder="请输入"
value={title}
onChange={(value) => {
setTitle(value);
console.log(`onChange: ${value}`);
}}
onBlur={(value) => console.log(`onBlur: ${value}`)}
/>
</Cell>
<Cell title="多行文本">
<Input
type="text"
rows={3}
placeholder="请输入"
type="text"
placeholder="请输入"
value={content}
onChange={setContent}
/>
</Cell>
</>
)
}

ReactDOM.render(<Demo />, mountNode);
```



## 输入类型

```jsx
import { useState, useRef } from 'react';
import { Input, Cell, Button } from 'zarm';

class Demo extends React.Component {
state = {
focused: false,
number: '',
};

render() {
return (
<>
<Cell title="数字">
<Input
ref={(ref) => { this.manualFocus = ref; }}
type="number"
placeholder="type is number"
value={this.state.number}
focused={this.state.focused}
onFocus={value => console.log(`onFocus: ${value}`)}
onBlur={value => console.log(`onBlur: ${value}`)}
onChange={value => console.log(`onChange: ${value}`)}
/>
</Cell>

<Cell title="金额">
<Input type="price" placeholder="type is price" />
</Cell>

<Cell title="身份证">
<Input type="idcard" placeholder="type is idcard" />
</Cell>

<Cell>
<Button size="xs" theme="primary" onClick={() => this.manualFocus.focus()}>click to focus the first input</Button>
</Cell>
</>
)
}
const Demo = () => {
const focusInput = useRef();
const [value, setValue] = useState('');

return (
<>
<Cell title="数字">
<Input
ref={focusInput}
type="number"
placeholder="type is number"
value={value}
onChange={setValue}
/>
</Cell>

<Cell title="金额">
<Input type="price" placeholder="type is price" defaultValue={value} />
</Cell>

<Cell title="身份证">
<Input type="idcard" placeholder="type is idcard" />
</Cell>

<Cell>
<Button size="xs" theme="primary" onClick={() => focusInput.current.focus()}>click to focus the first input</Button>
</Cell>
</>
)
}

ReactDOM.render(<Demo />, mountNode);
Expand Down Expand Up @@ -129,39 +131,31 @@ ReactDOM.render(
## 高度自适应

```jsx
import { useState } from 'react';
import { Input, Cell } from 'zarm';

class Demo extends React.Component {
state = {
inputValue: '',
};

handleInputChange = (value) => {
this.setState({
inputValue: value,
});
}
const Demo = () => {
const [value, setValue] = useState('');

render() {
return (
<Cell title="多行文本">
<Input
autoHeight
type="text"
rows={3}
placeholder="请输入"
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
</Cell>
);
}
return (
<Cell title="多行文本">
<Input
autoHeight
type="text"
rows={3}
placeholder="请输入"
value={value}
onChange={setValue}
/>
</Cell>
);
}

ReactDOM.render(<Demo />, mountNode);
```



## 显示输入字数
```jsx
import { useState } from 'react';
Expand Down

0 comments on commit e3bb8d1

Please sign in to comment.