我创建了一个React应用。它可以在IE,Opera,Chrome,FF中正常运行。状态更新后在Edge中呈现一个组件时出现问题。我无法使用Chrome的React Devtools帮助自己,因为它在这里应该都能正常工作。
我的组件是两个输入字段的组合。一个是数字输入,可以由用户操纵,另一个是显示相同的数字值,但格式设置为货币字符串。当用户单击该字段时,具有格式化值的字段将隐藏并显示未格式化的输入字段。当用户离开可编辑输入时,隐藏的之前输入会再次显示。
由于我希望每次触发onchange
事件时状态都会改变,因此其他输入也会在每个onchange
上更新。
这是因为它是隐藏的吗?
这是代码,我试图尽可能简化它:
class MasterComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
Rows: [
{ Id: 1, Name: 'Row 1', Price: 11 },
{ Id: 2, Name: 'Row 2', Price: 21 },
{ Id: 3, Name: 'Row 3', Price: 13 }
]
}
this.changeObjectValue = this.changeObjectValue.bind(this);
}
render() {
return <MCVE changeObjectValue={this.changeObjectValue} rows={this.state.Rows}></MCVE>
}
changeObjectValue(rowId, propertyName, value) {
// define which list user wants to change
let list = this.state['Rows'];
let changedList = [];
// change value
list.forEach(element => {
if (element.Id == rowId) {
element[propertyName] = value;
}
changedList.push(element);
});
// dynamically set objct name frmo parameters
this.setState({ Rows: changedList });
}
}
class MCVE extends React.Component {
render() {
return <table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{this.props.rows.map((r, index) =>
<tr key={r.Id}>
<td>
<input readOnly value={r.Id}></input>
</td>
<td><input name="Name" onChange={event => this.changeInput(event, r.Id)} value={r.Name}></input></td>
<td>
<input name="Price" className="edit" type="hidden" onBlur={event => toggleEditDisplay(event)} onChange={event => this.changeInput(event, r.Id)} value={r.Price}></input>
<input name="Price" className="display" readOnly onClick={event => toggleEditDisplay(event)} value={formatMoney(r.Price)}></input>
</td>
</tr>
)}
</tbody>
</table>
;
}
changeInput(event, rowId) {
let propertyName = event.target.name;
this.props.changeObjectValue(
rowId,
propertyName,
event.target.value);
}
}
function toggleEditDisplay(event) {
let el = event.target;
// if has class 'edit' else has class 'display'
if (el.className.split(/\s+/).filter(e => e == 'edit').length > 0) {
let elToToggle = el.parentElement.getElementsByClassName('display')[0];
el.type = "hidden";
elToToggle.type = "text";
}
else {
let elToToggle = el.parentElement.getElementsByClassName('edit')[0];
el.type = "hidden";
elToToggle.type = "number";
}
}
function formatMoney(amount, decimalCount = 2, decimal = ",", thousands = ".", currencySymbol = '€', ignoreCurrencySymbol = false) {
try {
decimalCount = Math.abs(decimalCount);
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
let j = (i.length > 3) ? i.length % 3 : 0;
return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "") + (ignoreCurrencySymbol ? "" : currencySymbol);
} catch (e) {
console.log(e)
}
};
ReactDOM.render(<MasterComponent />, document.getElementById('app'));
最低HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="reactScript.js"></script>
</body>
</html>
答案 0 :(得分:1)
经过测试,问题似乎与type="hidden"
有关,我们可以修改代码并使用CSS display属性来隐藏或显示输入元素。请检查以下步骤:
在index.css文件中添加以下CSS样式:
.edit{
display:none;
}
修改toggleEditDisplay函数:
function toggleEditDisplay(event) {
let el = event.target;
// if has class 'edit' else has class 'display'
if (el.className.split(/\s+/).filter(e => e == 'edit').length > 0) {
let elToToggle = el.parentElement.getElementsByClassName('display')[0];
el.style.display ='none';
elToToggle.type = "text";
elToToggle.style.display ='block';
}
else {
let elToToggle = el.parentElement.children[0];
//el.type = "hidden";
el.style.display ='none';
elToToggle.type = "number";
elToToggle.style.display ='block';
}
el.focus();
}
在Edge浏览器中的结果如下: