问题
I have come across a very strange issue that I can't wrap my head around. I'm currently working with an create-react-app using react 16.3 and Antd 3.11 framework and I have created a table which inside it's header column renders a component with an onChange event attached.
The issue comes when I focus the input for the first time.
I lose focus on first key event, and afterwards when I click the field again, it remains focused until I click something else.
Here is the example I have been using: https://ant.design/components/table/
and the code that follows.
import {
Table, Input, Button, Icon,
} from 'antd';
const data = [{
key: '1',
name: 'John Brown',
age: 32,
address: 'New York No. 1 Lake Park',
}, {
key: '2',
name: 'Joe Black',
age: 42,
address: 'London No. 1 Lake Park',
}, {
key: '3',
name: 'Jim Green',
age: 32,
address: 'Sidney No. 1 Lake Park',
}, {
key: '4',
name: 'Jim Red',
age: 32,
address: 'London No. 2 Lake Park',
}];
class App extends React.Component {
state = {
searchText: '',
};
handleSearch = (selectedKeys, confirm) => () => {
confirm();
this.setState({ searchText: selectedKeys[0] });
}
handleReset = clearFilters => () => {
clearFilters();
this.setState({ searchText: '' });
}
render() {
const columns = [{
title: 'Name',
dataIndex: 'name',
key: 'name',
filterDropdown: ({
setSelectedKeys, selectedKeys, confirm, clearFilters,
}) => (
<div className="custom-filter-dropdown">
<Input
ref={ele => this.searchInput = ele}
placeholder="Search name"
value={selectedKeys[0]}
onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={this.handleSearch(selectedKeys, confirm)}
/>
<Button type="primary" onClick={this.handleSearch(selectedKeys, confirm)}>Search</Button>
<Button onClick={this.handleReset(clearFilters)}>Reset</Button>
</div>
),
filterIcon: filtered => <Icon type="smile-o" style={{ color: filtered ? '#108ee9' : '#aaa' }} />,
onFilter: (value, record) => record.name.toLowerCase().includes(value.toLowerCase()),
onFilterDropdownVisibleChange: (visible) => {
if (visible) {
setTimeout(() => {
this.searchInput.focus();
});
}
},
render: (text) => {
const { searchText } = this.state;
return searchText ? (
<span>
{text.split(new RegExp(`(${searchText})`, 'gi')).map((fragment, i) => (
fragment.toLowerCase() === searchText.toLowerCase()
? <span key={i} className="highlight">{fragment}</span> : fragment // eslint-disable-line
))}
</span>
) : text;
},
}, {
title: 'Age',
dataIndex: 'age',
key: 'age',
}, {
title: 'Address',
dataIndex: 'address',
key: 'address',
filters: [{
text: 'London',
value: 'London',
}, {
text: 'New York',
value: 'New York',
}],
onFilter: (value, record) => record.address.indexOf(value) === 0,
}];
return <Table columns={columns} dataSource={data} />;
}
}
ReactDOM.render(<App />, mountNode);
And the css that follows to that:
.custom-filter-dropdown {
padding: 8px;
border-radius: 6px;
background: #fff;
box-shadow: 0 1px 6px rgba(0, 0, 0, .2);
}
.custom-filter-dropdown input {
width: 130px;
margin-right: 8px;
}
.custom-filter-dropdown button {
margin-right: 8px;
}
.highlight {
color: #f50;
}
To quickly sum up things i've come to understand.
- The table rerenders the filterDropDown prop, filterIcon on every keystroke.
- The class component where the table is within does not rerender or trigger(componentDidUpdate)
- This works perfectly in Chrome, FireFox, Edge and the sample works in IE11 on antds website. however not in my app.
- All antd fields and regular fields which are rendered in my own components does not have this problem in any browser.
- Rendering the input components outside the render function does not work since it is not my component that rerenders it is the table component that triggers it's own update events
- I have also tried to change -ms-user-select: settings to different attributes to see weather that had an effect or not. fact was it only made it worse.
- I've tried to set input value as a state value to make it a controlled component, however when componentDidUpdate triggers and I programtically set .focus on my input it sets caretIndex lenght-1 instead of behind text. (I have manually tried to override selectionStart and SelectionEnd but without success
I'm sort of running out of ideas since what I have come to understand is that some other component is stealing the focus of my input box, however I have not been able to find the element even though I've used document.activeElement in almost every method and lifecycle event I could think of. All events point to the 'a' Input field having focus (not sure if this is the old or new one created, however I think it's the old one).
I have tried my best to explain my scenario and I hope someone out there in the world has come across a similar issue.
UPDATE: antd reasonly changed their table component so the example is a bit different on the webpage, however issue still remains the same.
回答1:
I hade the same behavior on IE11.
Could fix it with an additional onBlur on the Input field, that just set the focus to the currentTarget.
onBlurHandler = (e: React.FocusEvent<HTMLInputElement>) => {
e.currentTarget.focus();
};
来源:https://stackoverflow.com/questions/53780602/react-internet-explorer-11-input-loses-focus-after-first-onchange