使用 map() 和 JSX 渲染数据数组
Rendering an array of data with map() and JSX
我正在尝试用 jsx 渲染一个数组,这个数组内部有一个跨度,当试图渲染它时输出是 [object Object] 我正在尝试在里面添加一个工具提示,你能帮我理解为什么会这样吗?
我在 react-bootstrap-table-plus 库
中使用 BootstrapTable
我的代码:
<DataTableConfigurator
data={
this.props.configuracion.map(d => {
var s = d.servicios[0].fechaultimaactualizacion;
var ds = moment(s, 'DD - MM - YYYY HH:mm');
var fecha = ds.format('DD/MM/YYYY');
return {
NOMBRE: <a key={d.ID_TIPO_CONF} data-toggle="tooltip" title={["Última fecha actualización :" + fecha]}>{d.nombredivision} </a>,
ID_TIPO_CONF: d.iD_TIPO_CONFIGURACION == 1 ? 'Manual' : 'Automática',
}
}
}
>
我的 DataTableConfigurator 的属性:
class DataTableProperties extends PureComponent {
constructor(props) {
super(props);
this.state = {
originalData: this.props.data,
cloneData: [...this.props.data],
searchFilterValue: '',
noDataMessage: this.props.noDataMessage,
page: 1,
sizePerPage: this.props.sizePerPage || 5
};
}
componentWillUpdate(prevProps) {
if (prevProps.data.length != this.state.originalData.length) {
this.cloneOriginalData(prevProps.data);
} else {
if (prevProps.data.length != 0) {
var obj = [];
for (var i = 0; i < prevProps.data.length; i++) {
var e = prevProps.data[i];
if (e[Object.keys(e)[0]] != this.state.originalData[i][Object.keys(e)[0]]) {
this.cloneOriginalData(prevProps.data);
break;
}
}
//if (obj.length != 0) {
//}
}
}
}
componentWillUnmount() {
this.setState({
originalData: [],
cloneData: [],
searchFilterValue: '',
noDataMessage: '',
page: 1
});
}
cloneOriginalData = data => {
var originalData = data;
var cloneData = [...originalData];
this.setState({ originalData, cloneData });
}
searchFilter = input => {
var searchFilterValue = input.target.value;;
var originalData = this.state.originalData;
var cloneData = [];
if (searchFilterValue != '') {
for (var i = 0; i < originalData.length; i++) {
var row = originalData[i];
var keys = Object.keys(row);
for (var j = 0; j < keys.length; j++) {
var cell = row[keys[j]];
if (typeof cell !== 'object') {
cell = String(cell).toLowerCase();
if (cell.indexOf(searchFilterValue.toLowerCase()) > -1) {
cloneData.push(row);
break;
}
}
}
}
} else {
cloneData = [...originalData];
}
this.setState({ cloneData, searchFilterValue, page: 1 });
}
render() {
const customTotal = (from, to, size) => (
<span className="react-bootstrap-table-pagination-total">
Mostrando {from} a {to} de {size} Resultados
</span>
);
const headercolor = { color: "#FFFF" };
const options = {
paginationSize: 3,
pageStartIndex: 1,
sizePerPage: 15, // which size per page you want to locate as default
prePage: 'Atrás', // Previous page button text
nextPage: 'Siguiente', // Next page button text
firstPage: 'Primero', // First page button text
lastPage: 'Último', // Last page button text
noDataText: (<div className="text-center">No se encontraron datos</div>),
showTotal: true,
paginationShowsTotal: customTotal,
page: this.state.page,
onPageChange: e => { this.setState({ page: e }); },
disablePageTitle: true,
sizePerPageList: [{
text: this.state.sizePerPage, value: this.state.sizePerPage
}, {
text: this.state.sizePerPage * 2, value: this.state.sizePerPage * 2
}, {
text: 'Todos', value: this.state.cloneData.length
}]
};
//function priceFormatter(cell, row) {
// return '<span></span>' + row;
//}
return (
<div>
<div className="row mb-3">
<div className="col-1 offset-9">
<label className="p-1">Buscar:</label>
</div>
<div className="col-2">
<input type="text" className="form-control form-control w-100" value={this.state.searchFilterValue} onChange={input => { this.searchFilter(input); }} />
</div>
</div>
<div className="row">
<div className="col-12">
<BootstrapTable striped hover condensed
key={`data_${new Date().getTime()}`}
headerStyle={{ background: '#df6727' }}
containerStyle={{ border: '#f0f0f0 1.5px solid' }}
data={this.state.cloneData}
bootstrap3={true}
noDataIndication={() => (<div className="text-center"> {this.state.noDataMessage == null ? 'No se encontraron resultados' : this.state.noDataMessage}</div>)}
pagination={true}
options={options}
>
<TableHeaderColumn width='200' dataField="NOMBRE"><div style={headercolor}>División</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="ID_TIPO_CONF" isKey={true}><div style={headercolor}>Tipo Conf.</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV01"><div style={headercolor}>Servicio 1</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV02"><div style={headercolor}>Servicio 2</div></TableHeaderColumn>
<TableHeaderColumn width='200' dataField="NOMBRESERV03"><div style={headercolor}>Servicio 3</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV04"><div style={headercolor}>Servicio 4</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV05"><div style={headercolor}>Servicio 5</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV06"><div style={headercolor}>Servicio 6</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV07"><div style={headercolor}>Servicio 7</div></TableHeaderColumn>
</BootstrapTable>
</div>
</div>
</div>
);
}
}
export default DataTableProperties;
有什么解决办法吗?
获得它的唯一方法是在 string
字段中打印 object
。
示例:
console.log(`${{}}`);
// [object Object]
console.log('' + {});
// [object Object]
console.log({});
// > {}
在<DataTableConfigurator />
中打印<a ...>{d.nombredivision}</a>
,然后出现“手册”,所以我想问题出在这里。
当你尝试像 <a>{{}}</a>
这样打印“[object Object]”的东西时。
这很奇怪,因为 React,它应该抛出 Error: Objects are not valid as a React child
。简单 HTML/JS 让你这样做,结果正是你已经得到的。
尝试调试 d.nombredivision
看看它到底是什么。
我的解决方案:在 DataTableConfigurator 中为每个 header 或元素创建一个函数:
1.- 其中行是您在原始列表中的行。
cellDivision(cell, row, enumObject, rowIndex) {
return (
<a data-toggle="tooltip" title={["Última fecha actualización :" + row.FECHA]}>
{row.NOMBRE}
</a>
)
}
2.- 在 header 列表中添加数据格式:
<TableHeaderColumn width="130" dataField="NOMBRE" dataFormat={this.cellDivision.bind(this)}><div style={headercolor}>División</div></TableHeaderColumn>
谢谢!
我正在尝试用 jsx 渲染一个数组,这个数组内部有一个跨度,当试图渲染它时输出是 [object Object] 我正在尝试在里面添加一个工具提示,你能帮我理解为什么会这样吗? 我在 react-bootstrap-table-plus 库
中使用 BootstrapTable我的代码:
<DataTableConfigurator
data={
this.props.configuracion.map(d => {
var s = d.servicios[0].fechaultimaactualizacion;
var ds = moment(s, 'DD - MM - YYYY HH:mm');
var fecha = ds.format('DD/MM/YYYY');
return {
NOMBRE: <a key={d.ID_TIPO_CONF} data-toggle="tooltip" title={["Última fecha actualización :" + fecha]}>{d.nombredivision} </a>,
ID_TIPO_CONF: d.iD_TIPO_CONFIGURACION == 1 ? 'Manual' : 'Automática',
}
}
}
>
我的 DataTableConfigurator 的属性:
class DataTableProperties extends PureComponent {
constructor(props) {
super(props);
this.state = {
originalData: this.props.data,
cloneData: [...this.props.data],
searchFilterValue: '',
noDataMessage: this.props.noDataMessage,
page: 1,
sizePerPage: this.props.sizePerPage || 5
};
}
componentWillUpdate(prevProps) {
if (prevProps.data.length != this.state.originalData.length) {
this.cloneOriginalData(prevProps.data);
} else {
if (prevProps.data.length != 0) {
var obj = [];
for (var i = 0; i < prevProps.data.length; i++) {
var e = prevProps.data[i];
if (e[Object.keys(e)[0]] != this.state.originalData[i][Object.keys(e)[0]]) {
this.cloneOriginalData(prevProps.data);
break;
}
}
//if (obj.length != 0) {
//}
}
}
}
componentWillUnmount() {
this.setState({
originalData: [],
cloneData: [],
searchFilterValue: '',
noDataMessage: '',
page: 1
});
}
cloneOriginalData = data => {
var originalData = data;
var cloneData = [...originalData];
this.setState({ originalData, cloneData });
}
searchFilter = input => {
var searchFilterValue = input.target.value;;
var originalData = this.state.originalData;
var cloneData = [];
if (searchFilterValue != '') {
for (var i = 0; i < originalData.length; i++) {
var row = originalData[i];
var keys = Object.keys(row);
for (var j = 0; j < keys.length; j++) {
var cell = row[keys[j]];
if (typeof cell !== 'object') {
cell = String(cell).toLowerCase();
if (cell.indexOf(searchFilterValue.toLowerCase()) > -1) {
cloneData.push(row);
break;
}
}
}
}
} else {
cloneData = [...originalData];
}
this.setState({ cloneData, searchFilterValue, page: 1 });
}
render() {
const customTotal = (from, to, size) => (
<span className="react-bootstrap-table-pagination-total">
Mostrando {from} a {to} de {size} Resultados
</span>
);
const headercolor = { color: "#FFFF" };
const options = {
paginationSize: 3,
pageStartIndex: 1,
sizePerPage: 15, // which size per page you want to locate as default
prePage: 'Atrás', // Previous page button text
nextPage: 'Siguiente', // Next page button text
firstPage: 'Primero', // First page button text
lastPage: 'Último', // Last page button text
noDataText: (<div className="text-center">No se encontraron datos</div>),
showTotal: true,
paginationShowsTotal: customTotal,
page: this.state.page,
onPageChange: e => { this.setState({ page: e }); },
disablePageTitle: true,
sizePerPageList: [{
text: this.state.sizePerPage, value: this.state.sizePerPage
}, {
text: this.state.sizePerPage * 2, value: this.state.sizePerPage * 2
}, {
text: 'Todos', value: this.state.cloneData.length
}]
};
//function priceFormatter(cell, row) {
// return '<span></span>' + row;
//}
return (
<div>
<div className="row mb-3">
<div className="col-1 offset-9">
<label className="p-1">Buscar:</label>
</div>
<div className="col-2">
<input type="text" className="form-control form-control w-100" value={this.state.searchFilterValue} onChange={input => { this.searchFilter(input); }} />
</div>
</div>
<div className="row">
<div className="col-12">
<BootstrapTable striped hover condensed
key={`data_${new Date().getTime()}`}
headerStyle={{ background: '#df6727' }}
containerStyle={{ border: '#f0f0f0 1.5px solid' }}
data={this.state.cloneData}
bootstrap3={true}
noDataIndication={() => (<div className="text-center"> {this.state.noDataMessage == null ? 'No se encontraron resultados' : this.state.noDataMessage}</div>)}
pagination={true}
options={options}
>
<TableHeaderColumn width='200' dataField="NOMBRE"><div style={headercolor}>División</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="ID_TIPO_CONF" isKey={true}><div style={headercolor}>Tipo Conf.</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV01"><div style={headercolor}>Servicio 1</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV02"><div style={headercolor}>Servicio 2</div></TableHeaderColumn>
<TableHeaderColumn width='200' dataField="NOMBRESERV03"><div style={headercolor}>Servicio 3</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV04"><div style={headercolor}>Servicio 4</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV05"><div style={headercolor}>Servicio 5</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV06"><div style={headercolor}>Servicio 6</div></TableHeaderColumn>
<TableHeaderColumn width='150' dataField="NOMBRESERV07"><div style={headercolor}>Servicio 7</div></TableHeaderColumn>
</BootstrapTable>
</div>
</div>
</div>
);
}
}
export default DataTableProperties;
有什么解决办法吗?
获得它的唯一方法是在 string
字段中打印 object
。
示例:
console.log(`${{}}`);
// [object Object]
console.log('' + {});
// [object Object]
console.log({});
// > {}
在<DataTableConfigurator />
中打印<a ...>{d.nombredivision}</a>
,然后出现“手册”,所以我想问题出在这里。
当你尝试像 <a>{{}}</a>
这样打印“[object Object]”的东西时。
这很奇怪,因为 React,它应该抛出 Error: Objects are not valid as a React child
。简单 HTML/JS 让你这样做,结果正是你已经得到的。
尝试调试 d.nombredivision
看看它到底是什么。
我的解决方案:在 DataTableConfigurator 中为每个 header 或元素创建一个函数:
1.- 其中行是您在原始列表中的行。
cellDivision(cell, row, enumObject, rowIndex) {
return (
<a data-toggle="tooltip" title={["Última fecha actualización :" + row.FECHA]}>
{row.NOMBRE}
</a>
)
}
2.- 在 header 列表中添加数据格式:
<TableHeaderColumn width="130" dataField="NOMBRE" dataFormat={this.cellDivision.bind(this)}><div style={headercolor}>División</div></TableHeaderColumn>
谢谢!