我是新来的要做出反应的人,所以请忍受任何非技术性的话。
我有一个显示table
标题的父组件,现在下一个是具有表的td
和一个td
的子组件,当用户单击时将添加button
添加button
。应该将类似的子组件作为兄弟组件添加到先前的子组件,并且此过程应继续进行。
子组件:
class ChildComp extends React.Component{
state = {
Avalue: {value: ''},
Bvalue: {value: ''},
Cvalue: {value: ''},
Dvalue: {value: ''},
Evalue: {value: ''},
Fvalue: {value: ''},
Gvalue: {value: ''},
}
AddanotherSimilarChildcomp=(e)=>{
e.preventDefault();
const historyData = {
A: this.state.A.value,
B:this.state.B.value,
C: this.state.C.value,
D: this.state.D.value,
E: this.state.E.value,
F: this.state.F.value,
G: this.state.G.value,
}
console.log(historyData);
//and should render another similar ChildComp component below the one in which the current ChildComp is present
}
handleChange=(e)=>{
e.preventDefault();
const target = e.target;
const inputName = target.name;
const inputValue = target.value;
this.setState({
[inputName] : {
value: inputValue,
}
});
}
render(){
return(
<tbody id="first-table-row">
<tr>
<td data-th="A"><input type="text" minmax="40" name="A" value={this.state.a.value} onChange={this.handleChange} /></td>
<td data-th="B"><input type="date" minmax="40" name="B" value={this.state.B.value} onChange={this.handleChange} /></td>
<td data-th="C"><input type="text" minmax="225" name="C" value={this.state.C.value} onChange={this.handleChange} /></td>
<td data-th="D"><input type="text" minmax="40" name="D"value={this.state.D.value} onChange={this.handleChange} /></td>
<td data-th="E"><input type="text" minmax="40" name="E" value={this.state.E.value} onChange={this.handleChange} /></td>
<td data-th="F"><input type="text" minmax="40" name="F" value={this.state.F.value} onChange={this.handleChange} /></td>
<td data-th="G">
<div id="samerow">
<span>{this.props.somedata}</span>
<input type="text" minmax="40" name="G"value={this.state.G.value} onChange={this.handleChange} />
</div>
</td>
<td className="save" ><button id="save-btn" onClick={this.AddanotherSimilarChildcomp} type='button'>Add</button></td>
</tr>
</tbody>
)
}
}
父组件:
class ParentComponent extends React.PureComponent{
render(){
return(
<div className='table-center' id='table1'>
<table className="rwd-table" id="tblBlah" >
<tbody>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
<th>F</th>
<th>G</th>
<th> </th>
</tr>
</tbody>
<ChildComp/>
</table>
</div>
)
}
}
答案 0 :(得分:1)
听起来好像您想在单击按钮后克隆行。让我知道这是否是您想要的。
希望这会有所帮助!
class ParentComponent extends React.Component {
render() {
return (
<div>
<table>
<tbody>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
<th>F</th>
<th>G</th>
<th> </th>
</tr>
</tbody>
<ChildComp
rows={[
[1, 2, 3, 4, 5, 6, 7],
[8, 9, 10, 11, 12, 13, 14],
[14, 15, 16, 17, 18, 19, 20]
]}
/>
</table>
</div>
);
}
}
class ChildComp extends React.Component {
state = {
tableRows: []
};
componentDidMount() {
this.setState({ tableRows: this.props.rows });
}
addNewRow = (rowToClone, index) => event => {
let newRows = [...this.state.tableRows];
newRows.splice(index, 0, rowToClone.map(i => `${i}` + `${i[0] || i}`));
this.setState({ tableRows: newRows });
};
render() {
return (
<tbody>
{this.state.tableRows.map((row, index) => {
return (
<tr>
{row.map(i => <td>{i}</td>)}
<td>
<button onClick={this.addNewRow(row, index + 1)}>
Clone Row
</button>
</td>
</tr>
);
})}
</tbody>
);
}
}
ReactDOM.render(<ParentComponent />, document.body);
table, th, tr, td {
border: 1px solid black;
}
table {
border-collapse: collapse;
}
td {
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
答案 1 :(得分:1)
我认为您使组件树的逻辑过于复杂。这就是我对您的问题的解释。
查看有效的沙箱:https://codesandbox.io/s/inspiring-wave-bpv7f
让Parent组件管理数据集是最有意义的。因此,所有涉及更新或添加数据集中内容的逻辑都应属于父级组件,而不是子级组件。
考虑这样的示例;
Parent.js
class App extends React.Component {
state = {
headers: ["name", "age", "job", "salary"],
data: [
[
{ name: "Bobby Hill", editting: false },
{ age: 13, editting: false },
{ job: "student", editting: false },
{ salary: 0, editting: false }
]
]
};
createHeaders = () => {
const { headers } = this.state;
return headers.map(item => <th className="table-header">{item}</th>);
};
createBody = () => {
const { data } = this.state;
return data.map((row, index) => (
<Child data={row} rowIndex={index} toggleEdit={this.toggleEdit} />
));
};
addRow = () => {
const { data } = this.state;
const rowTemplate = [
{ name: "", editting: true },
{ age: "", editting: true },
{ job: "", editting: true },
{ salary: "", editting: true }
];
this.setState({
data: [...data, rowTemplate]
});
};
toggleEdit = (rowIndex, cellIndex) => {
const dataCopy = [...this.state.data];
const itemToUpdate = dataCopy[rowIndex][cellIndex];
itemToUpdate.editting = !itemToUpdate.editting;
this.setState({
data: dataCopy
});
};
render() {
return (
<div className="table-center" id="table1">
<table className="rwd-table" id="tblBlah">
<tbody>
<tr>{this.createHeaders()}</tr>
{this.createBody()}
</tbody>
</table>
<button onClick={this.addRow}>Add Row</button>
</div>
);
}
}
在“父级”组件中,我们具有:
addRow
函数将向我们的数据集中添加一个新数组,
包含与每个表头/属性对应的对象。Child.js
import React from "react";
const Child = ({ data, rowIndex, toggleEdit }) => {
return (
<tr>
{data.map((cell, cellIndex) => (
<td
className="table-cell"
onDoubleClick={() => toggleEdit(rowIndex, cellIndex)}
>
{cell.editting ? (
<input value={Object.values(cell)[0]} />
) : (
<span>{Object.values(cell)[0]}</span>
)}
</td>
))}
</tr>
);
};
export default Child;
现在在“子”组件中: